<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!--<meta name="viewport" content="width=device-width, initial-scale=1">-->
    <meta name="viewport" content="width=device-width, initial-scale=0.6, user-scalable=no">
    <title>E7 Camp Simulator</title>
    <meta name="keywords" content="epic seven camping, epic 7 camping simulator, e7 camp simulator, epic 7 morale calculator, e7 raid, epic seven raid" />
    <meta name="description" content="Epic Seven Camping Simulator for Raid and Labyrinth. Add your roster to find the best team combination with high morale!" />
  
    <!--Favicon-->
    <link rel="apple-touch-icon" sizes="180x180" href="../../favicons/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="../../favicons/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="../../favicons/favicon-16x16.png">
    <link rel="manifest" href="../../favicons/site.webmanifest">
    <link rel="mask-icon" href="../../favicons/safari-pinned-tab.svg" color="#5bbad5">
    <link rel="shortcut icon" href="../../favicons/favicon.ico">
    <meta name="msapplication-TileColor" content="#da532c">
    <meta name="msapplication-config" content="../../favicons/browserconfig.xml">
    <meta name="theme-color" content="#252B35">
    <meta property="og:type" content="website">
    <meta property="og:site_name" content="CeciliaBot">
    <meta property="og:image" content="/favicons/android-chrome-256x256.png">
    <meta property="og:image:width" content="256">
    <meta property="og:image:height" content="256">

    <script src="https://cdnjs.loli.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.loli.net/ajax/libs/js-combinatorics/0.5.5/combinatorics.min.js" async></script>
    <script src="https://cdnjs.loli.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/font-awesome/5.13.1/css/all.min.css" async>
    <!--<link rel="preload" href="https://cdnjs.loli.net/ajax/libs/font-awesome/5.13.1/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">-->

    <!--<link rel="preload" href="https://i.imgur.com/NDUMMYK.png" as="image" media="(max-width: 90px)">-->
    <style>
:root {
	--font-color: #424242;
	--bg-color: #fff;
  --bg-color-secondary: #f1f1f1;
	--search-primary-color: #f1f1f1;
	--search-border-color: #666666;
	--colore-check-eroi: green;
	--icon-bar: #555;
	--icon-bar-alt: #36393f;
	--icon-bar-active: #4CAF50;
}


  /* variabili del tema*/
[data-theme="dark"] {
  --font-color: #A1AEBD;
  --bg-color: #252B35;
  --bg-color-secondary: #1e2126;
  --search-primary-color: #181C22;
  --search-border-color: #0e0f11;
  --colore-check-eroi: red;
  --icon-bar: #1e2126;
  --icon-bar-alt: #252B35;
  --icon-bar-active: #4CAF50;
}
  
body {
  font-family: Arial, Helvetica, sans-serif;
  background-color: var(--bg-color);
  overscroll-behavior-y: contain; /* Prevent pull-to-refresh on mobile */
  color: var(--font-color); /* font color */
}

html, div, span, form { /*Firefox scrollbar*/
  -ms-overflow-style: none;
  scrollbar-width: none;
}
::-webkit-scrollbar { /*Chrome scrollbar*/
  display: none;
}

[v-cloak] {
  display:none;
}
/* Full-width input fields */
input[type=text], input[type=password] {
  /*width: 100%;*/
  padding: 12px 20px;
  margin: 8px 0;
  display: inline-block;
  /*border: 1px solid #ccc;*/
  box-sizing: border-box;
}

/* Disable outline on click (focus-visible is not supported by chrome)
*:focus:not(.focus-visible) {
  outline: none;
}
*/

/* Set a style for all buttons */
.button_login {
  background-color: #4CAF50;
  color: white;
  padding: 14px 20px;
  margin: 8px 0;
  border: none;
  cursor: pointer;
  /*width: 100%;*/
}

.button_login:hover {
  opacity: 0.8;
}

/* Extra styles for the cancel button */
.button_cancelbtn {
  width: auto;
  padding: 14px 20px;
  margin: 8px 0;
  border: none;
  color: white;
  cursor: pointer;
  background-color: #f44336;
}

/* Center the image and position the close button */
.imgcontainer {
  text-align: center;
  margin: 24px 0 12px 0;
  position: relative;
}

img.avatar {
  width: 200px;
  border-radius: 50%;
}

.container {
  padding: 16px;
}

span.psw {
  float: right;
  padding-top: 16px;
}

/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 60; /* toolbar's z-index = 50 */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
  box-sizing: border-box;
}
.modal-open {
    overflow: hidden;
    margin-bottom: 100%; /*Fix for firefox*/
}
/* Modal Content/Box */
.modal-content {
  margin: 2% auto auto; /* 5% from the top, 15% from the bottom and centered */
  border: 4px solid #776048;
  border-radius: 12px;
  width: 80%; /* Could be more or less, depending on screen size */
  max-height: 90%;
  padding: 10px;
  background-color:var(--search-primary-color); 
  color:var(--font-color);
}
.modal-big {
  height: 90%;
}
.modal-small {
  max-width: 760px;
  overflow: scroll;
}
.modal-title {
  width: 100%;
  font-size: 35px;
  text-align: initial;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow-x: hidden;
}
.modal-text {
  width: 100%;
  font-size: 18px;
  text-align: initial;
}
.modal-three-parts {
  display: flex; 
  flex-direction: column;
}
.modal-three-parts > div {
  padding: 16px;
}
.modal-three-parts > div:first-of-type {
  flex: 0 0 5%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  border-bottom: solid thin #776048;
  position:relative
}
.modal-three-parts > div:not(:first-of-type) {
  overflow: scroll;
  flex: 1; 
  text-align: center;
}
.modal-three-parts > div:last-of-type {
  flex: 0 0 5%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  border-top: solid thin #776048;
  min-height: fit-content;
  overflow: hidden;
}
.modal-button {
  cursor: pointer;
  height: 48px; 
  min-width: 130px; 
  background-color: var(--bg-color-secondary); 
  border: 1px solid rgb(119, 96, 72); 
  border-radius: 10px; 
  color: var(--font-color); 
  font-size: 20px; 
  padding: 5px 20px;
  outline: none;
}
.modal-button:not(:last-of-type) {
  margin-right: 30px;
}
.modal-button:hover {
  opacity: 0.6;
}
/* E7 style buttons */
.green-btn {
  border: none;
  background-color: #3ea406;
  box-shadow: inset 0 40px 10px rgba(0, 0, 0, 0.37), inset 0 -12px 10px #07F95A78, inset 0 -3px 0px rgb(133, 255, 164), inset -10px 20px 30px rgba(0, 0, 0, 0.3), inset 10px 30px 20px rgba(2, 77, 27, 0.3);
  color: white;
  text-shadow: 0 0px 3px black;
}
.red-btn {
  border: none;
  background-color: #a40606;
  box-shadow: inset 0 40px 10px rgba(0, 0, 0, 0.37), inset 0 -12px 10px #F9070778, inset 0 -3px 0px rgb(255, 133, 133), inset -10px 20px 30px rgba(0, 0, 0, 0.3), inset 10px 30px 20px rgba(77, 2, 2, 0.3);
  color: white;
  text-shadow: 0 0px 3px black;
}
.brown-btn {
  border: none;
  background-color: #a44906;
  box-shadow: inset 0 40px 10px rgba(0, 0, 0, 0.37), inset 0 -12px 10px #F98F0778, inset 0 -3px 0px rgb(255, 173, 133), inset -10px 20px 30px rgba(0, 0, 0, 0.3), inset 10px 30px 20px rgba(77, 27, 2, 0.3);
  color: white;
  text-shadow: 0 0px 3px black;
}
/* The Close Button (x) */
.close {
  position: absolute;
  right: 25px;
  top: 0;
  color: var(--font-color);
  font-size: 35px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: red;
  cursor: pointer;
}

/* Add Zoom Animation */
.animate {
  animation: animatezoom 0.5s;
  -webkit-animation: animatezoom 0.5s;
}

@keyframes animatezoom {
  from {transform: scale(0)} 
  to {transform: scale(1)}
}

@-webkit-keyframes animatezoom {
  from {-webkit-transform: scale(0)} 
  to {-webkit-transform: scale(1)}
}

/* Change styles for span and cancel button on extra small screens */
@media screen and (max-width: 300px) {
  span.psw {
     display: block;
     float: none;
  }
  .cancelbtn {
     width: 100%;
  }
}

div.toolbar {
  position: fixed;
  bottom: 0;
  right: 0;
  width: 100%;
  border: 3px solid #73AD21;
}

.noselect {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.heroImgList {
  position: relative;
  padding: 12px;
  font-weight: bold;
  font-size:24px;
  color: var(--font-color);/*color: #221461;*/
  display:inline-block;
  vertical-align: top;
  transition: all .2s ease;
  -moz-transition: all .2s ease;
  -ms-transition: all .2s ease;
  -o-transition: all .2s ease;
}
.imgResults {
  padding: 0 !important;
  cursor: default !important;
}
.imgResults:hover {
  background-color: transparent !important;
}
.heroAvatar {
  height: 100%;
  width: 100%;
  /* Style alt text*/
  display: block;
  font-size: 12px;
  font-weight: normal;
  word-break: keep-all;
  overflow: hidden;
}
@media (hover: hover) { /* most likely pc */
  .heroImgList:hover {
    background-color: var(--search-primary-color);
    cursor: pointer;
  }
  .hoverIcon:hover {
    transform: scale(1.3);
    z-index: 1;
  }
  .modal {
    backdrop-filter: blur(8px);
  }
}
.heroNameLabel {
  font-weight: normal;
  font-size: 14px;
  margin: 5px 0 0;
  min-height: 34px;
  text-align: center;
  text-overflow: ellipsis;
  overflow: hidden;
}

.heroInTeam {
  background-color:green;
}
  
/* The Close Button (x) */
.removeHero {
  position: relative;
  color: #A1AEBD;
  font-size: 20px;
  font-weight: bold;
  /*margin-left: -5%;*/
  vertical-align: bottom;
}
.removeHero:hover,
.removeHero:focus {
  color: red;
  cursor: pointer;
}
/* The Close Button (x) */
.removecartesian {
  top: 0;
  color: #000;
  font-size: 35px;
  font-weight: bold;
}

.removecartesian:hover,
.removecartesian:focus {
  color: red;
  cursor: pointer;
}

.center {
  max-width: 800px;
  margin: auto;
}
.topics {
  text-align:center; 
  font-family:sans-serif;
  font-size:16px;
  min-width: 100px;
}
  
  
  
.search_hero_area {
  position: relative;
  display: inline-block;
  text-align: center;
  margin-right: 30px; /* 5%*/
  margin-bottom: 18px;

}
.search_hero_filter {
  background-color: var(--search-primary-color); /*  */
  border: none;
  text-align: center;
  font-size:20px;
  color: var(--font-color);
  width: 50px;
  height: 50px;
  padding: 10px 8px;
  text-align: center;
  text-decoration: none;
  position: relative;
  top:0px;
  display: inline-block;
  font-size: 10px;
  /*border-style: ridge;
  border-width: thin;
  border-color: var(--search-border-color);*/
  vertical-align: top;
  outline: none;
} 
.search_hero_filter div { /* per il testo dei tasti */
  text-align: center;
  font-size:18px;
  max-height:20px;
  height:100%;
}
.search_hero_filter input { /* Casella di testo */
  text-align: center;
  font-size:20px;
}
.search_hero_filter img { /* per le immagini dei tasti */
  text-align: center;
  height:70%;
}
.search_hero_filter.active { /* tasto premuto*/
  background-color: var(--search-border-color);
  color: white;
  outline: none;
}
.box_advanced_settings {
	background: var(--search-primary-color);
  color: var(--font-color);
	border-radius: 15px;
}

.adv_settings_elem {
  width: 120px;
  display: inline-block;
  padding: 12px;
  text-align: center;
  position: relative;
  box-sizing: border-box;
}

.class-quantity-container {
  position: absolute;
  height: 60px;
  width: 60px;
  left: 50%;
  transform: translateX(-50%);
}
.class-quantity-container > .incrementa {
  position: absolute;
  bottom: -15px;
  right: 0;
  cursor: pointer;
  padding: 4px 8px;
  background-color: var(--bg-color);
  color: green;
  border-radius: 50px;
}
.class-quantity-container > .decrementa {
  position: absolute;
  bottom: -15px;
  left: 0;
  cursor: pointer;
  padding: 4px 10px;
  background-color: var(--bg-color);
  color: red;
  border-radius: 50px;
}
.class-quantity-container > .quantity_curr_quantity {
  position: absolute;
  top: -8px;
  left: -5px;
  background-color: green;
  color: white;
  border-radius: 40px;
  padding: 5px 10px;
}

.searchBox {
  padding-top: 5px;
  padding-bottom: 5px;
  width: 250px;
  height: 40px;
  font-size: 20px;
  vertical-align: top;
  border-radius: 6px 0 0 6px;
  border-color: var(--search-border-color);
}
	
.search_input {
  background-color: #4CAF50;
  color: white;
  height: 40px;
  float: right;
  padding: 6px 10px;
  margin-top: 8px;
  margin-right: 16px;
  font-size: 17px;
  border: none;
  cursor: pointer;
  border-radius: 0 6px 6px 0;
}
  
/* Icon Bar CSS */
.icon-bar {
  position:fixed;
  bottom: 0;
  right: 0;
  width: 100%;
  background-color: #555;
  z-index: 50;
}

.icon-bar span {
  float: left;
  width: 20%;
  text-align: center;
  padding: 12px 0;
  transition: all 0.3s ease;
  color: white;
  font-size: 36px;
}
icon-bar span img {
  position: relative;
  top: -5px;
  margin-bottom: -10px;
  height: 40px;
}

.icon-bar span:hover:not(.active-icon-bar) {
  background-color: #000;
}

.vertical-icon-bar {
  position: fixed; 
  z-index: 50;
  top: 0; 
  left: 0; 
  height: 100vh;
  width: 90px; 
  background-color: var(--icon-bar);
  overflow: scroll;
  overscroll-behavior: contain;
  scrollbar-width: none; /* FireFox */
  -ms-overflow-style: none;
}

.vertical-icon-bar span {
  cursor: pointer;
  display: block;
  text-align: center;
  transition: all 0.3s ease;
  color: white;
  font-size: 36px;
  width: 75px;
  height: 75px;
  background-color: var(--icon-bar-alt);
  margin-left: 8px;
  margin-top: 10px;
  border-radius: 28px;
}

.vertical-icon-bar span:hover:not(.active-icon-bar) {
  background-color: #000;
}

.vertical-icon-bar span i, .vertical-icon-bar span img {
    transform: translate(0,-52%);
    margin-top: 50%;
}

.active-icon-bar {
  background-color: var(--icon-bar-active) !important;
} 
                  .topics {
                    text-align:center; 
                    font-family:sans-serif;
                    font-size:16px
                  }




                  .switch {
                    position: relative;
                    display: inline-block;
                    width: 60px;
                    height: 35px;
                  }

                  /* Hide default HTML checkbox */
                  .switch input {
                    opacity: 0;
                    width: 0;
                    height: 0;
                  }

                  /* The slider */
                  .slider {
                    position: absolute;
                    cursor: pointer;
                    width: 60px;
                    top: 0;
                    /*left: 0;*/
                    right: 0;
                    bottom: 0;
                    background-color: #ccc;
                    -webkit-transition: .4s;
                    transition: .4s;
                  }

                  .slider:before {
                    position: absolute;
                    content: "";
                    height: 26px;
                    width: 26px;
                    left: 4px;
                    bottom: 4px;
                    background-color: white;
                    -webkit-transition: .4s;
                    transition: .4s;
                  }

                  input:checked + .slider {
                    background-color: #2196F3;
                  }

                  input:focus + .slider {
                    box-shadow: 0 0 1px #2196F3;
                  }

                  input:checked + .slider:before {
                    -webkit-transform: translateX(26px);
                    -ms-transform: translateX(26px);
                    transform: translateX(26px);
                  }

                  /* Rounded sliders */
                  .slider.round {
                    border-radius: 34px;
                  }

                  .slider.round:before {
                    border-radius: 50%;
                  }

  
/* Lock icon */
.top-right {
  position: absolute;
  top: -12%;
  right: -7%;
}
.top-left {
  position: absolute;
  top: -10px;
  left: 6px;
  color: var(--colore-check-eroi);
}
.center_img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
@keyframes fadeIn { 
  from { opacity: 0; } 
}

.animate-flicker {
    animation: fadeIn 1s infinite alternate;
}
 

.dropdown {
  position: relative;
  display: inline-block;
}
.dropdown-content {
  display: none;
  position: absolute;
  background-color: var(--search-primary-color);
  min-width: 160px;
  max-width: 500px;
  /*left: -40px;*/
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 2;
}

.dropdown-content > div, .dropdown-content > a {
  color: var(--font-color);
  padding: 12px 16px;
  text-decoration: none;
  display: block;
  cursor: pointer;
}
.dropdown-content > span {
  color: var(--font-color);
  padding: 12px 16px;
  width: 500px;
  text-decoration: none;
  display: block;
  box-sizing: border-box;
}
.dropdown-content > div:hover, .dropdown-content > a:hover {
  background-color: var(--search-border-color);
  color: white;
  transition: display 2s; 
}
.dropdown:hover > .dropdown-content {display: block;}
/*.dropdown:hover > .dropdown-content:active {transition-delay: 1s; display: none;}*/

.extras_grid {
  display: grid;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 300px);
}
.extra_icon {
  position: relative;
  margin: 20px;
  text-align: center;
}
.extra_icon:hover {
  cursor: pointer;
}
.extra_icon span {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
  
.label {
  padding: 12px;
  display: inline-flex;
  position: relative;
  margin: auto;
  cursor: pointer;
  align-items: center;
  flex-direction: column;
}

.label::before {
  background-color: white;
  color: white;
  content: " ";
  display: block;
  border-radius: 50%;
  position: absolute;
  top: 5px;
  left: 10px;
  width: 25px;
  height: 25px;
  text-align: center;
  line-height: 28px;
  transition-duration: 0.4s;
  transform: scale(0);
  z-index:1;
}

.label img {
  height: 100px;
  width: 100px;
  transition-duration: 0.2s;
  transform-origin: 50% 50%;
}

:checked+.label {
  border-color: #ddd;
}

:checked+.label::before {
  content: "✓";
  /*background-color: grey;*/
  background-color: green;
  transform: scale(1);
}


/* display as list */
.displaylistTable {
  width:100%;
  max-width: 700px;
  border-spacing:10px;
}
.displaylistTable tr {
  padding: 20px;
}
.displayListTable td {
  display:inline;
}
.displaylistTable tr div {
  height: 110px;
  width: 100%;
  vertical-align: middle;
  font-size: 20px;
}
.displaylistTable tr img {
   position:relative;
   width:70px;
   vertical-align: middle;
   left:10px;
   top:13px;
}
.displaylistTable tr span {
  position:relative;
  padding-left: 10px;
  top:17px;
}
.displaylistTable tr:nth-child(odd) div {
  background-color: var(--search-primary-color);
  color: var(--font-color);
  border-radius: 15px;
}

.displaylistTable tr div:hover {
  background-color: var(--search-border-color);
  color: white;
  border-radius: 15px;
}

.displaylistTableIcons {
  font-size:38px;
  /*color: var(--colore-check-eroi);*/
  float: right;
  padding:10px;
  position:relative;
  top:35px;
  right:20px;
}

.displaylistTableIcons:hover {
  color: white;
}

.maps_table {
  width: 100%;
  border-collapse: collapse;
}

.vert_table_title {
  text-orientation: mixed;
  text-transform: uppercase;
  max-width: 50px;
  writing-mode: vertical-rl;
  font-size: 30px;
}

.maps_column {
  text-align: center;
}
.maps_column > span {
	position: relative;
	height: 200px;
	margin: 20px 15px;
	display: inline-block;
}
.maps_column > span > span {
	pointer-events: none;
	position: absolute;
	top: 0;
	left: 0;
	margin-top: 100px;
	margin-left: 50%;
	transform: translate(-50%,-50%);
	font-size: 25px;
	color: white;
	text-shadow: 1px 1px 0px black, 1px -1px 0px black, -1px 1px 0px black, -1px -1px 0px black;
}

.maps_column > span img {
	image-rendering: optimizespeed;
	height: 200px;
	filter: brightness(50%);/* blur(2px);*/
	border: 2px;
	border-color: black;
	transition: all .3s ease;
}

.maps_column > span img:hover {
	cursor: pointer;
	filter: brightness(.2);/* blur(2px);*/
}

#snackbar {
  visibility: hidden;
  min-width: 250px;
  max-width: 70%;
  background-color: #333;
  color: #fff;
  text-align: center;
  border-radius: 25px;
  padding: 16px;
  position: fixed;
  z-index: 100; /* always on top. Loading screen z-index = 10 */
  left: 50%;
  top: 30px;
  font-size: 17px;
  transform: translate(-50%);
  word-wrap: break-word;
  overflow-wrap: break-word;
}

#snackbar.show {
  visibility: visible;
  -webkit-animation: fadein_snackbar 0.5s, fadeout_snackbar 0.5s 2.5s;
  animation: fadein_snackbar 0.5s, fadeout_snackbar 0.5s 2.5s;
}

@-webkit-keyframes fadein_snackbar {
  from {top: 0; opacity: 0;} 
  to {top: 30px; opacity: 1;}
}

@keyframes fadein_snackbar {
  from {top: 0; opacity: 0;}
  to {top: 30px; opacity: 1;}
}

@-webkit-keyframes fadeout_snackbar {
  from {top: 30px; opacity: 1;} 
  to {top: 0; opacity: 0;}
}

@keyframes fadeout_snackbar {
  from {top: 30px; opacity: 1;}
  to {top: 0; opacity: 0;}
}

.blur {
  background-color: rgba(0, 0, 0, 0.61);
  backdrop-filter: blur(5px);
  color: white;
}

.rightClickIconMenu {
  display: inline-block;
  cursor: pointer;
  height: 50px;
  width: 33.33%; /* 3 icons */
  background-size: 45px;
  background-repeat: no-repeat;
  background-position: center;
  padding: 10px 0;
}
.rightClickIconMenu:hover {
  background-color: var(--search-border-color);
}

.welcome {
  display: grid;
  margin-top: -10px;
  grid-template-columns: repeat(1, 100%); 
  grid-template-rows: 40px;
}

.bottom-border {
  width: 100%;
  border-style: none none outset none;
}

.welcome_menu {
  /*background-color: rgba(0,0,0, 0.2);*/
  text-align: center;
  margin-right: auto; 
  margin-left: auto;
  width: 100%;
}

.welcome_menu span {
  position: relative;
  top: 12px;
  font-size: 20px;
  /*padding:5px;*/
  padding-left: 2px;
  padding-right: 2px;
  padding-top: 5px;
  width: 100%;
  margin-right: 3px;
  margin-left: 3px;

}


.active_welcome {
  border-style: none none outset none;
  border-color: rgb(221, 51, 8);
}

.tab_style {
  display: inline-block;
  background-color: var(--search-border-color);
  border-radius: 12px 12px 0 0;
  width: 50%;
  padding-top: 7px;
  height: 30px;
  color: white;
  text-align: center;
}
.activetab {
  background-color: var(--bg-color-secondary);
  color: var(--font-color)
}

.histogram_bar {
  border-radius: 15px;
  height: 40px;
  background: linear-gradient(to bottom, rgb(128, 194, 254) 30%, rgb(14, 175, 227) 100%);
}

.histogram_bar span {
  position: relative;
  white-space: nowrap;
  left: 100%;
  margin-left: 20px;
  top: 10px;
  bottom: 0;
  vertical-align: middle;
  height: 40px;
}


.pagination {
  list-style-type: none;
  text-align: center;
  padding: 0 0 40px 0;
}

.pagination-item {
  display: inline-block;
  margin: 0 auto 0 auto;
}
.pagination-item button {
  background-color: var(--search-primary-color);
  color: var(--font-color);
  border: none;
  height: 40px;
  min-width: 40px;
  cursor: pointer;
  outline: none;
}

@media screen and (max-width: 600px) { /* zoom pagintion buttons on small devices*/ 
  .pagination-item button {
    height: 60px;
    min-width: 60px;
  }
}
.pagination-item .activePage {
  background-color: var(--search-border-color);
  color: #ffffff;
}

.check {
  position: relative;
  display: block;
  font-size: 20px;
  color: var(--font-color);
  user-select: none;
  margin: 10px 0;
  padding-left: 1.7em;
  padding-top: .1em;
}
/* Hide the browser's default checkbox */
.check input[type="checkbox"] {
  display: none;
  position: absolute;
}
.checkmark {
  position: absolute;
  left: 0;
  width: 1em;
  height: 1em;
  margin-top: -.1em;
  border: 0.16em solid #555;
  border-radius: 20%;
  transition: all ease-out 0.2s;
  white-space: nowrap;
}
/* Change border color when checked */
.check input:checked ~ .checkmark {
  border: 0.16em solid var(--icon-bar-active);
}
.check input[type="checkbox"]:hover ~ .checkmark {
  cursor: pointer;
}
/* Hide marker
.checkmark:after {
} */
/* Show the checkmark when checked */
.check input:checked ~ .checkmark:after {
  opacity: 1;
  width: 1.1em;
}
/* marker style */
.check .checkmark:after {
  content: "";
  position: absolute;
  width: 0;
  height: 0.35em;
  border-bottom: 0.16em solid var(--icon-bar-active);
  border-left: 0.16em solid var(--icon-bar-active);
  top: 25%;
  left: 50%;
  transform-origin: bottom left;
  transform: rotate(-45deg);
  opacity: 0;
  transition: all ease-out 0.2s;
}

.wrapper-hero-info {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
}
.rarity-5 {
  background-image: url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png);
  background-size: 25%;
  background-position: 90%,70%,50%,30%,10%;
  background-position-y: 99%;
  background-repeat: no-repeat;
}
.rarity-4 {
  background-image: url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png);
  background-size: 25%;
  background-position: 80%,60%,40%,20%;
  background-position-y: 99%;
  background-repeat: no-repeat;
}
.rarity-3 {
  background-image: url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png),url(https://assets.epicsevendb.com/star/cm_icon_star.png);
  background-size: 25%;
  background-position: 70%,50%,30%;
  background-position-y: 99%;
  background-repeat: no-repeat;
}
.attribute-role {
  position: absolute;
  top: -5%;
  left: -5%;
  height: 110%;
  width: 110%;
  background-position: 0% 0%, 100% 0%;
  background-repeat: no-repeat;
  background-size: 32%;
}
</style>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://um.iwarship.cn/shipdata" data-website-id="30f2812b-900e-4265-9dfa-cddfdeb04360"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-161715700-1');
</script>
</head>
<body>
  <div id="app" style="margin-bottom: 70px"><!-- vue.js -->
    <!--WELCOME WINDOW START-->
    <div id="welcome" style="display: '';" v-cloak>
      <div id="contenuto_welcome" class="welcome">
        <div class="welcome_menu" style="position: sticky; top: 0; background: var(--bg-color);">
          <span class="active_welcome" name="welcome_element" onmouseover="welcome_toggle('welcome',this)">
            {{strings.welcome}}
          </span>
          <span name="welcome_element" onmouseover="welcome_toggle('whats_new',this)">
            {{strings.whats_new}}
          </span>
          <span name="welcome_element" onmouseover="welcome_toggle('instructions',this)">
            {{strings.instructions}}
          </span>
          <span name="welcome_element" onmouseover="welcome_toggle('cool_websites',this)">
            {{strings.websites}}
          </span>
          <span name="welcome_element" onmouseover="welcome_toggle('credits',this)">
            {{strings.credits}}
          </span>
        </div>
        <div id="welcome_content">
          <template v-if="lingua == 'cn'"> <!-- Welcome windows Simplified CHINESE content goes here -->
            <div id="welcome_message" style="height: 100%">
              <h2 style="text-align: center;">{{strings.messaggio_di_benvenuto}}<br><a href="https://epicsevendb.com/" style="text-decoration: none;color:red"><u>{{strings.data_by}}</u></a>
              </h2>
              <div style="color: orangered; text-align: center;">
                右键点击英雄头像显示更多信息!
              </div>
              <div v-if='!Object.keys(myHeroesList).length' onmouseover="" style="cursor: pointer; color: orangered; text-align: center; margin-top: 30vh; font-size: 30px;" onclick="welcome_toggle('instructions',{})">
                第一次使用?<br> 点击查看简明使用教程.
              </div>
              <!-- Copyright stuff if needed
              <div style="width: 100%; position: absolute; bottom: 10%; text-align: center;">
                All game content and assets are trademarks and copyrights of SUPERCREATIVE Corp and/or Smilegate Megaport.<br>
                This site is fan made, not affiliated with SUPERCREATIVE Corp and/or Smilegate Megaport. 
              </div>
              -->
            </div>
            <div id="whats_new_content" style="display: none;">
              <ul>
                <li style="color:#007FFF">
                  <b>28/01/2021</b>: {{strings.multilock}} 更新和其它UI改进<br>
                  更多排序方式: {{strings.name}}, {{strings.attribute}}, {{strings.classe}}, {{strings.stars}}, {{strings.ingame_id}} (和添加日期)<br>
                  优化{{strings.multilock}}的英雄筛选功能: 现在你可以在这个模块中筛选英雄<br>
                  去掉 {{strings.multilock}} 的"(Beta)" 标签因为它已经能正常工作, 现在你可以将同一个英雄锁定在多个槽位来根据你的英雄池创建自定义规则。
                  如何使用{{strings.multilock}}? 你有4个英雄槽位，你可以把任意数量的英雄放入其中任意一个槽位，最终的排列组合里，每个槽位只会出现你对应放入的英雄。 
                  例如你可以把所有单体攻击的英雄放入 "槽位1" 把所有AOE英雄放入 "槽位2" 最终结果会是一个单体DPS+一个AOE + 你英雄池中任意两个其它英雄。 这个工具可以自由组合带来无限可能!
                </li>
                <li>
                  <b>02/01/2021</b>: 启动速度优化<br>
                </li>
                <li style="color:#007FFF">
                  <b>12/09/2020</b>: 右键菜单<br>
                  右键 (手机长按) 可以打开快捷菜单 可以查看英雄技能 或者跳转到 Epic Seven DB 查看更多英雄信息 或者跳转至e7herder.com查看英雄的模型.<br>
                  已知问题: 火狐手机版长按会同时显示浏览器自带的长按菜单.
                </li>
                <li style="color:#007FFF">
                  <b>08/09/2020</b>: 高级选项新增职业数量设定<br>
                 你现在可以设置队伍中包含的 精灵师/骑士/战士 的最低数量<br>
                  例如你可以设置成 2骑士2精灵师 提高迷宫成功率.
                </li>
                <li>
                  <b>29/08/2020</b>: 添加计算进度条 :D<br>
                  现在选了高级设置以后，计算会显示进度条.  例如 2020 年 8月 29 日的版本需要花17分钟计算 187 个英雄带高级设置的所有排列组合, 锁定一个英雄后计算耗时20秒.<br>
                  不选择高级设置则不会显示进度条，因为最长计算时间仅4秒左右.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>20/08/2020</b>: 添加泰文 (ภาษาไทย) 支持<br>
                  Epic Seven DB API 更新后可以选择泰文作为数据显示语言 (菜单依旧为英文).
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>15/08/2020</b>:<br>
                  Firefox浏览器兼容性优化.<br>
                  尼科斯特的圣所地图，由game8.co提供<br>
                  暂时没有制偶师波萝莱珍的迷宫对话数据 :( .
                </li>
                <li style="color:#007FFF">
                  <b>21/07/2020</b>: 队伍必须包含驱散角色<br>
                  你可以选择这项用于保证队伍里至少包含一位驱散角色.<br>
                  注意: 克罗爱等需要专属装备才能驱散或者赛瑞斯等减少buff回合数的英雄都被算作驱散角色.<br>
                  现在如果计算英雄数量很多的情况下，计算时会提示。大量计算虽然不会导致浏览器崩溃，但是在计算力较弱的设备(比如低端手机)上会耗费较长时间。你也可以在选项里打开通知，在计算完毕后通知你 :P .
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>19/07/2020</b>: Bug 修复<br>
                  删除一个英雄时会自动锁定列表中的下一个英雄或者锁定删除掉的英雄.
                  在执行操作前添加了1毫秒的延迟用于修正这个bug.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>18/07/2020</b>: 结果页添加分页<br>
                  结果现在会分页显示用于节约你的内存，每页显示50个结果.
                  TODO: 给"常用队伍/英雄"功能添加分页功能.
                </li>
                <li style="color:#007FFF">
                  <b>21/06/2020</b> 垂直工具栏.<br>
                  宽屏设备上自动使用垂直工具栏. 可以在设置里切换回经典水平工具栏.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>20/06/2020</b>: 计算结果中去掉了重复英雄 (转职英雄和转职前同时出现) & 其它小功能更新!<br>
                  去掉了包含重复英雄的队伍 例如萝里娜和指挥官萝里娜. 如果你同时锁定了一个英雄的转职版本和普通版本将会报错.<br>
                  如果计算耗时太长，你现在可以中止计算.<br>
                  现在你可以"多重锁定"功能可以快速选择英雄.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  15/06/2020: 优化算法，提高了计算心情的速度!<br>
                  高速计算不支持高级设置, 如果启用了高级设置，将使用原有算法计算".<br>
                  新选项 "{{strings.add_displayed_heroes}}" 和 "{{strings.remove_displayed_heroes}}" 用于批量添加和删除英雄.
                </li>
                <li style="color:rgb(255, 60, 0)">
                  添加常用队伍统计!<br>
                  在下方工具栏点击齿轮图标 -> "{{strings.most_saved_teams}}".
                </li>
                <li style="color:rgb(0, 255, 136)">
                  现在你可以选择结果的显示数量.<br>
                  使用方法: 选择 "高级设置" => 点击右上角齿轮图标 => 选中 "{{strings.numero_massimo_risultati}}" 或/与 "{{strings.morale_minimo_risultati}}" 然后输入相应的数量.<br>
                  请不要把 "{{strings.numero_massimo_risultati}}" 设置的很高 或者把"{{strings.morale_minimo_risultati}}" 设置得很低，你的浏览器很可能因为计算大量的结果而花费很长的加载时间.
                  默认显示心情最高的 200 个结果.
                </li>
                <li style="color:#007FFF">
                  新功能: "生成URL链接"<br>
                  在设置里选择生成URL链接将会生成一个保存了你英雄列表的链接.<br>
                  你可以在任何设备上使用这个链接.<br>
                  如果你用生成的链接打开将会覆盖当前设备已经保存的英雄列表.<br>
                  该功能仅用于跨设备/浏览器快速同步个人英雄列表，你的英雄列表依旧是自动保存的.
                </li>
                <li style="color:#007FFF">
                  设置里加入调试选项.<br>
                  打开可以右键(手机长按)查看对话列表.
                </li>
                <li>
                  默认语言将根据你浏览器的语言自动选择.<br>
                  你可以在设置里切换语言.
                </li>
                <li style="color:rgb(0, 255, 136)">
                  现在你可以选择德语，葡萄牙语，法语和西班牙语了.<br>
                  只有法语是菜单和数据完全翻译. 再次感谢 <a href="https://www.reddit.com/user/TriATK/">TriATK</a> 提供的法文翻译.<br>
                  德语，葡萄牙语，和西班牙语仅有数据翻译 (英雄名称, 对话, buffs 和 debuff) 如果你想提供翻译请联系我.<br>
                </li>
                <li style="color:rgb(0, 255, 136)">
                  添加简体中文，日文，韩文:<br>
                  日韩的菜单未翻译 游戏数据已翻译, 简中有完整的菜单和数据翻译.<br>
                  感谢 <a href="https://www.reddit.com/user/TriATK/">TriATK</a> 提供的中文翻译.<br>
                </li>
                <li>
                  添加通知功能:<br>
                  启用通知将会在计算完毕时发送通知.<br>
                  本功能适用于电脑端将网页放到后台时提示计算结果，并不会发送其它类型的通知!
                </li>
                <li style="color:rgb(0, 255, 136)">
                  添加锁定多人功能(Beta):<br>
                  添加你的英雄到4个栏位中 (每个栏位对应结果页上的相同位置), 如果你重复添加相同的英雄，最终结果里只会出现一次!
                </li>
                <li style="color:#007FFF">
                  现在你可以保存计算的结果:<br>
                  在结果页面点击 <i class="fa fa-save" aria-hidden="true"></i>  , 然后输入你自己定义的队伍名称并点击 "保存".<br>
                  你保存的队伍将显示在 <i class="fa fa-cog" aria-hidden="true"></i>  的设置窗口 你可以修改并删除他们.
                </li>
                <li>
                  启动的时候会生成一个web worker用于处理计算结果, 这会保证你的浏览器不会出现 "页面失去响应".<br>
                  这个工具可以计算全部 35.208.615 种可能的排列组合并且不会崩溃 (运行中会保持低RAM占用率) 但是会花费更长的时间 (13-17 分钟, 锁定一个英雄后约 20 秒);
                </li>
              </ul>
            </div>
            <div id="instructions_content" style="display: none; text-align: center; margin-top: 10%;">
              简明教程:
              <div style="padding-top: 30px;">
                <i class="fa fa-plus" aria-hidden="true"></i>: 添加英雄到你的英雄列表.<br><br>
                <i class="fa fa-pencil-alt" aria-hidden="true"></i>: 查看你的英雄列表. 点击英雄头像锁定，锁定后必定出现在计算结果中. 点击 <font color="red">x</font> 移除英雄.<br><br>
                <i class="fa fa-book" aria-hidden="true"></i> (可选): 高级设置. (启用高级设置会稍微降低运算速度)<br><br>
                <i class="fas fa-fire" aria-hidden="true"></i>点击篝火图标进行计算. (你的英雄列表至少要包含4个英雄)<br><br>
                <i class="fa fa-question-circle" aria-hidden="true"></i>: 这是帮助图标. 点击可以查看每项功能的具体说明.<br><br>
                <i class="fa fa-cog"></i>: 网站功能设定.<br>
              </div>
            </div>
            <div id="cool_websites_content" style="display: none; text-align: center; margin-top: 10%;">
              不容错过的实用网站:
              <p><a href="https://epicsevendb.com/cn">EpicSevenDB</a> by RaphaelDDL</p>
              <p><a href="https://e7herder.com/">E7herder</a> 有非常酷的角色模型动画查看器</p>
              <p><a href="https://maphe.github.io/e7-damage-calc/zh/index.html">Epic 7 伤害计算器</a> by Maphe</p>
              <p><a href="https://www.e7leaks.com/">Epic 7 Leaks</a> by Maphe</p>
              <p><a href="https://epic7pvp.com">Epic7pvp.com</a> for PVP community events</p>
              <p><a href="https://meowyih.github.io/epic7-gear/index.html?lang=cn">装备评分计算器</a> by meowyih</p>
              <p><a href="http://www.epicseventools.com/Home/LabMoraleOptimizer">E7 Tools</a> by Budandan</p>
              <p><a href="https://gamepress.gg/epicseven/">GamePress.gg</a></p>
            </div>
            <div id="credits_content" style="display: none;">
              <div style="position: absolute; bottom: 10%; text-align: center; right: 0; left: 0;">
                <br>英文地狱迷宫地图: <a href="https://www.reddit.com/user/C0NNECT1NG/">u/C0NNECT1NG</a> (<a href="https://www.reddit.com/r/EpicSeven/comments/flg4b1/complete_hell_raid_map/">Reddit post</a>)
                <br>普通迷宫地图&中文迷宫地图: TriATK
                <br>中文/法文翻译: TriATK
                <br>联系原作者(英语或意大利语): <a href="https://www.reddit.com/user/UsernameSniped/">u/UsernameSniped</a>
                <br>Discord: gio#0898
              </div>
            </div>
          </template>
          <template v-else-if="lingua == 'zht'"> <!-- Welcome windows Traditional CHINESE content goes here -->
            <div id="welcome_message" style="height: 100%">
              <h2 style="text-align: center;">{{strings.messaggio_di_benvenuto}}<br><a href="https://epicsevendb.com/" style="text-decoration: none;color:red"><u>{{strings.data_by}}</u></a>
              </h2>
              <div style="color: orangered; text-align: center;">
                右鍵點選英雄頭像顯示更多信息!
              </div>
              <div v-if='!Object.keys(myHeroesList).length' onmouseover="" style="cursor: pointer; color: orangered; text-align: center; margin-top: 30vh; font-size: 30px;" onclick="welcome_toggle('instructions',{})">
                第一次使用?<br> 點擊查看簡明使用教程.
              </div>
              <!-- Copyright stuff if needed
              <div style="width: 100%; position: absolute; bottom: 10%; text-align: center;">
                All game content and assets are trademarks and copyrights of SUPERCREATIVE Corp and/or Smilegate Megaport.<br>
                This site is fan made, not affiliated with SUPERCREATIVE Corp and/or Smilegate Megaport. 
              </div>
              -->
            </div>
            <div id="whats_new_content" style="display: none;">
              <ul>
                <li style="color:#007FFF">
                  <b>12/09/2020</b>: 右鍵菜單<br>
                  右鍵 (手機長按) 可以打開快捷菜單 可以檢視英雄技能 或者跳轉到 Epic Seven DB 檢視更多英雄信息 或者跳轉至e7herder.com檢視英雄的模型.<br>
                  已知問題: 火狐手機版長按會同時顯示瀏覽器自帶的長按菜單.
                </li>
                <li style="color:#007FFF">
                  <b>08/09/2020</b>: 高級選項新增職業數量設定<br>
                 你現在可以設定隊伍中包含的 精靈師/騎士/戰士 的最低數量<br>
                  例如你可以設定成 2騎士2精靈師 提高迷宮成功率.
                </li>
                <li>
                  <b>29/08/2020</b>: 添加計算進度條 :D<br>
                  現在選了高級設定以後，計算會顯示進度條.  例如 2020 年 8月 29 日的版本需要花17分鍾計算 187 個英雄帶高級設定的所有排列組合, 鎖定一個英雄後計算耗時20秒.<br>
                  不選擇高級設定則不會顯示進度條，因為最長計算時間僅4秒左右.
                </li>
                <li style="color:rgb(0, 148, 32)">
                <b>20/08/2020</b>: 添加泰文 (ภาษาไทย) 支援<br>
                  Epic Seven DB API 更新後可以選擇泰文作為數據顯示語言 (菜單依舊為英文).
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>15/08/2020</b>:<br>
                  Firefox瀏覽器兼容性優化.<br>
                  尼科斯特的聖所地圖，由game8.co提供<br>
                  暫時冇有製偶師波蘿萊珍的迷宮對話數據 :( .
                </li>
                <li style="color:#007FFF">
                  <b>21/07/2020</b>: 隊伍必須包含驅散角色<br>
                  你可以選擇這項用於保證隊伍裏至少包含一位驅散角色.<br>
                  註意: 克羅愛等需要專屬裝備才能驅散或者賽瑞斯等減少buff回合數的英雄都被算作驅散角色.<br>
                  現在如果計算英雄數量很多的情況下，計算時會提示。大量計算雖然不會導緻瀏覽器崩潰，但是在計算力較弱的設備(比如低端手機)上會耗費較長時間。你也可以在選項裏打開通知，在計算完畢後通知你 :P .
                <li style="color:rgb(0, 148, 32)">
                  <b>19/07/2020</b>: Bug 修複<br>
                  刪除一個英雄時會自動鎖定列表中的下一個英雄或者鎖定刪除掉的英雄.
                  在執行操作前添加了1毫秒的延遲用於修正這個bug.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>18/07/2020</b>: 結果頁添加分頁<br>
                  結果現在會分頁顯示用於節約你的記憶體，每頁顯示50個結果.
                  TODO: 給"常用隊伍/英雄"功能添加分頁功能.
                </li>
                <li style="color:#007FFF">
                  <b>21/06/2020</b> 垂直工具欄.<br>
                  寬熒幕設備上自動使用垂直工具欄. 可以在設定裏切換回經典水平工具欄.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>20/06/2020</b>: 計算結果中去掉了重復英雄 (轉職英雄和轉職前同時出現) & 其它小功能更新!<br>
                  去掉了包含重復英雄的隊伍 例如蘿裏娜和指揮官蘿裏娜. 如果你同時鎖定了一個英雄的轉職版本和普通版本將會報錯.<br>
                  如果計算耗時太長，你現在可以中止計算.<br>
                  現在你可以"多重鎖定"功能可以快速選擇英雄.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  15/06/2020: 優化算法，提高了計算心情的速度!<br>
                  高速計算不支持高級設置, 如果啟用了高級設置，將使用原有算法計算".<br>
                  新選項 "{{strings.add_displayed_heroes}}" 和 "{{strings.remove_displayed_heroes}}" 用於批量添加和刪除英雄.                 
                </li>
                <li style="color:rgb(255, 60, 0)">
                  添加常用隊伍統計!<br>
                  在下方工具欄點擊齒輪圖標 -> "{{strings.most_saved_teams}}".
                </li>
                <li style="color:rgb(0, 255, 136)">
                  現在你可以選擇結果的顯示數量.<br>
                  使用方法: 選擇 "高級設定" => 點擊右上角齒輪圖標 => 選中 "{{strings.numero_massimo_risultati}}" 或/與 "{{strings.morale_minimo_risultati}}" 然後輸入相應的數量.<br>
                  請不要把 "{{strings.numero_massimo_risultati}}" 設定的很高 或者把"{{strings.morale_minimo_risultati}}" 設定得很低，你的瀏覽器很可能因為計算大量的結果而花費很長的加載時間.
                  默認顯示心情最高的 200 個結果.
                </li>
                <li style="color:#007FFF">
                  新功能: "生成URL鏈接"<br>
                  在設定裏選擇生成URL鏈接將會生成一個保存了你英雄列表的鏈接.<br>
                  你可以在任何設備上使用這個鏈接.<br>
                  如果你用生成的鏈接打開將會覆蓋當前設備已經保存的英雄列表.<br>
                  該功能僅用於跨設備/瀏覽器快速同步個人英雄列表，你的英雄列表依舊是自動保存的.
                </li>
                <li style="color:#007FFF">
                  設定裏加入調試選項.<br>
                  打開可以右鍵(手機長按)查看對話列表.
                </li>
                <li>
                  默認語言將根據你瀏覽器的語言自動選擇.<br>
                  你可以在設定裏切換語言.
                </li>
                <li style="color:rgb(0, 255, 136)">
                  現在你可以選擇德語，葡萄牙語，法語和西班牙語了.<br>
                  只有法語是菜單和數據完全翻譯. 再次感謝 <a href="https://www.reddit.com/user/TriATK/">TriATK</a> 提供的法文翻譯.<br>
                  德語，葡萄牙語，和西班牙語僅有數據翻譯 (英雄名稱, 對話, buffs 和 debuff) 如果你想提供翻譯請聯系我.<br>
                </li>
                <li style="color:rgb(0, 255, 136)">
                  添加簡體中文，日文，韓文:<br>
                  日韓的菜單未翻譯 遊戲數據已翻譯, 簡中有完整的菜單和數據翻譯.<br>
                  感謝 <a href="https://www.reddit.com/user/TriATK/">TriATK</a> 提供的中文翻譯.<br>
                </li>
                <li>
                  添加通知功能:<br>
                  啟用通知將會在計算完畢時發送通知.<br>
                  本功能適用於電腦端將網頁放到後臺時提示計算結果，並不會發送其它類型的通知!
                </li>
                <li style="color:rgb(0, 255, 136)">
                  添加鎖定多人功能(Beta):<br>
                  添加你的英雄到4個欄位中 (每個欄位對應結果頁上的相同位置), 如果你重復添加相同的英雄，最終結果裏只會出現一次!
                </li>
                <li style="color:#007FFF">
                  現在你可以保存計算的結果:<br>
                  在結果頁面點擊 <i class="fa fa-save" aria-hidden="true"></i>  , 然後輸入你自己定義的隊伍名稱並點擊 "保存".<br>
                  你保存的隊伍將顯示在 <i class="fa fa-cog" aria-hidden="true"></i>  的設定窗口 你可以修改並刪除他們.
                </li>
                <li>
                  啟動的時候會生成一個web worker用於處理計算結果, 這會保證你的瀏覽器不會出現 "頁面失去響應".<br>
                  這個工具可以計算全部 35.208.615 種可能的排列組合並且不會崩潰 (運行中會保持低RAM占用率) 但是會花費更長的時間 (13-17 分鐘, 鎖定一個英雄後約 20 秒);
                </li>
              </ul>
            </div>
            <div id="instructions_content" style="display: none; text-align: center; margin-top: 10%;">
              簡明教程:
              <div style="padding-top: 30px;">
                <i class="fa fa-plus" aria-hidden="true"></i>: 添加英雄到你的英雄列表.<br><br>
                <i class="fa fa-pencil-alt" aria-hidden="true"></i>: 查看你的英雄列表. 點擊英雄頭像鎖定，鎖定後必定出現在計算結果中. 點擊 <font color="red">x</font> 移除英雄.<br><br>
                <i class="fa fa-book" aria-hidden="true"></i> (可選): 高級設定. (啟用高級設定會稍微降低運算速度)<br><br>
                <i class="fas fa-fire" aria-hidden="true"></i>點擊篝火圖標進行計算. (你的英雄列表至少要包含4個英雄)<br><br>
                <i class="fa fa-question-circle" aria-hidden="true"></i>: 這是幫助圖標. 點擊可以查看每項功能的具體說明.<br><br>
                <i class="fa fa-cog"></i>: 網站功能設定.<br>
              </div>
            </div>
            <div id="cool_websites_content" style="display: none; text-align: center; margin-top: 10%;">
              不容錯過的實用網站:
              <p><a href="https://epicsevendb.com/tw">EpicSevenDB</a> by RaphaelDDL</p>
              <p><a href="https://e7herder.com/">E7herder</a> 有非常酷的角色模型動畫查看器</p>
              <p><a href="https://maphe.github.io/e7-damage-calc/zhTW/index.html">Epic 7 傷害計算器</a> by Maphe</p>
              <p><a href="https://www.e7leaks.com/">Epic 7 Leaks</a> by Maphe</p>
              <p><a href="https://epic7pvp.com">Epic7pvp.com</a> for PVP community events</p>
              <p><a href="https://meowyih.github.io/epic7-gear/index.html?lang=tw">裝備評分計算器</a> by meowyih</p>
              <p><a href="http://www.epicseventools.com/Home/LabMoraleOptimizer">E7 Tools</a> by Budandan</p>
              <p><a href="https://gamepress.gg/epicseven/">GamePress.gg</a></p>
            </div>
            <div id="credits_content" style="display: none;">
              <div style="position: absolute; bottom: 10%; text-align: center; right: 0; left: 0;">
                <br>英文地獄迷宮地圖: <a href="https://www.reddit.com/user/C0NNECT1NG/">u/C0NNECT1NG</a> (<a href="https://www.reddit.com/r/EpicSeven/comments/flg4b1/complete_hell_raid_map/">Reddit post</a>)
                <br>普通迷宮地圖&中文迷宮地圖: TriATK
                <br>中文/法文翻譯: TriATK
                <br>聯系原作者(英語或意大利語): <a href="https://www.reddit.com/user/UsernameSniped/">u/UsernameSniped</a>
                <br>Discord: gio#0898
              </div>
            </div>
          </template>
          <template v-else> <!-- Welcome windows ENG content goes here -->
            <div id="welcome_message" style="height: 100%">
              <h2 style="text-align: center;">{{strings.messaggio_di_benvenuto}}<br><a href="https://epicsevendb.com/" style="text-decoration: none;color:red"><u>{{strings.data_by}}</u></a>
              </h2>
              <div style="color: orangered; text-align: center;">
                "Conqueror Lilias" data has been updated fixing incorrect values
              </div>
              <div v-if='!Object.keys(myHeroesList).length' onmouseover="" style="cursor: pointer; color: orangered; text-align: center; margin-top: 30vh; font-size: 30px;" onclick="welcome_toggle('instructions',{})">
                First time here?<br> Click here for a quick guide.
              </div>
              <!-- Copyright stuff if needed
              <div style="width: 100%; position: absolute; bottom: 10%; text-align: center;">
                All game content and assets are trademarks and copyrights of SUPERCREATIVE Corp and/or Smilegate Megaport.<br>
                This site is fan made, not affiliated with SUPERCREATIVE Corp and/or Smilegate Megaport. 
              </div>
              -->
            </div>
            <div id="whats_new_content" style="display: none;">
              <ul>
                <li style="color: #007FFF">
                  <b>09/11/2022</b>: Improvements to advanced settings<br>
                  You can now select the number of Attributes (Fire / Ice / Earth / Light / Dark) you want in your team.<br>
                  You can now select a negative value (for both roles and attributes) and that attribute/role will be excluded from your teams.<br>
                </li>
                <li>
                  <b>30/12/2021</b>: Updated ML Lilias data:<br>
                  ML Lilias was previously added to the website with incorrect camping values. Please manually update teams that include her!
                </li>
                <li style="color: red">
                  <b>22/10/2021</b>: Removed Belief and replaced with Faith<br>
                  If you have saved a saved team with Belief and Faith please update it.
                </li>
                <li style="color: #007FFF">
                  <b>08/07/2021</b>: More sorting options<br>
                  Now you can sort by the reaction value to camping topics, for example you can sort by "Advice".<br>
                  Topic filtering will be added soon (TM).
                </li>
                <li style="color: #007FFF">
                  <b>22/06/2021</b>: Custom Lab Maker<br>
                  A simple route maker for Nixied and Raid.<br>
                  To access it go to "Maps" and click on "Custom route".
                </li>
                <li style="color: #007FFF">
                  <b>19/02/2021</b>: Friendship Farming?<br>
                  If you don't care about morale and you're just friendship farming in labyrinth you can use this new function to quickly find the best companions for your character.<br>
                  Right click a character and select "{{strings.calculate_highest_friendship}}". The results will be displayed in the same tab as normal morale but the numbers displayed under the "{{strings.morale}}" column are the friendship gains for your character not your team's morale.<br>
                  The result team will have a size of 3 or less heroes you can fill the remaining free spaces with fodder or any hero you wish when building you team.<br>
                  Since most of the top teams will have the same results the current layout may be subject to some changes.<br>
                  At the moment locked heroes will be ignored when using this function.<br>
                  Note: You cannot use the Save function normally available for teams.
                </li>
                <li style="color:#ff0000">
                  <b>05/02/2021</b>: ! IMPORTANT !<br>
                  After the update on the 4th of February many of the camping values have changed.<br>
                  Morale and friendship now will always match.<br>
                  If you have any saved team on this tool make sure to manually update it!<br>
                  Also add Senya's camping values (they could change after her release).
                </li>
                <li style="color:#007FFF">
                  <b>28/01/2021</b>: Multi-lock (Cartesian Lock) update and other ui changes<br>
                  More sorting options: Name, Attribute, Class, Rarity, ID (and date for your roster)<br>
                  Better character selector for cartesian lock: you can filter and search herooes in the modal window<br>
                  Removed "(Beta)" tag from Multi-lock because it's working as intended, now you can lock the same hero in multiple slots allowing you to create custom rules with your roster
                  How to use Multi-lock? You have 4 slots and you can put any hero and as many heroes as you desire and this tool will take a hero from each slot and combine it with heroes from other slots. For examle you can put all your single target DPSs in "Slot 1" and your AOE DPSs in "Slot 2" the result will be a combination of Single Target DPS + AOE DPS + 2 other random heroes from your roster. The potential of this tool is infinite!
                </li>
                <li>
                  <b>02/01/2021</b>: Boot speed improvements<br>
                </li>
                <li style="color:#007FFF">
                  <b>12/09/2020</b>: Contextual menu<br>
                  Right click (long tap on mobile) on a character to open a quick menu where you can read that hero's skills and quickly jump to Epic Seven DB to read more or open the model viewer on e7herder.com.<br>
                  Known issue: on mobile FireFox the default long tap menu will also be displayed.
                </li>
                <li style="color:#007FFF">
                  <b>08/09/2020</b>: Request a specific number of character classes<br>
                  You can now set a specific minimum number of soul-weavers/knights/warriors etc...<br>
                  For example you can request 2 soul-weavers and a knight for safer runs.
                </li>
                <li>
                  <b>02/09/2020</b>: Advanced Settings speed improvements<br>
                  Now it can calculate all the combinations under 7 minutes instead of 17 minutes (as of 02/09/2020 - on PC), under 8 seconds with 1 hero locked, with advanced settings on<br>
                  The time required will increase as new heroes are released.
                </li>
                <li>
                  <b>29/08/2020</b>: New Progress bar :D<br>
                  When you select advanced settings a progress bar will be displayed while calculating team combinations. As of 29/08/2020 it takes 17 mins to calculate all the combinations with 187 heroes in your roster and advanced settings on, it takes 20 sec if you lock 1 hero.<br>
                  The progress bar is not displayed if no advanced settings are selected because it takes only 4 seconds to calculate the best combinations regardless of the roster's size.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>20/08/2020</b>: Add Thai (ภาษาไทย) language support<br>
                  With the Epic Seven DB API update you can now select Thai for the game data (menus are still english).
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>15/08/2020</b>:<br>
                  Some Firefox changes.<br>
                  Nixied maps from game8.co<br>
                  Still no Pearlhorizon SC camping data sorry :( .
                </li>
                <li style="color:#007FFF">
                  <b>21/07/2020</b>: Team must include dispel<br>
                  You can check this option if you want your teams to have at least one hero that can remove buffs from enemies.<br>
                  Note: Chloe is tagged as dispeller because of her EE (can remove buffs with S2), I also tagged cerise and some other heroes that reduce buff duration because there are just a few heroes that can dispel.<br>
                  A warning will now appear in the "Advanced settings" to warn you about your team size and the time needed to calculate all combinations with advanced settings on (locking heroes can reduce the time required). This tool can calculate all combinations without crashing but it will require a long time. If you don't care and want to try anyway you can activate notifications in the settings window to let you know we results are ready :P .
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>19/07/2020</b>: Bug fix<br>
                  After removing a hero the next hero on the list would automatically get locked or the removed hero could lock itself.<br>
                  Fixed by delaying the function by 1ms after the left click is released.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>18/07/2020</b>: Pagination for Results Page<br>
                  Results are now split into pages to save up memory on your device. Each page will show 50 teams.
                  TODO: Add pagination to "Most saved teams" to save more memory when visiting that function.
                </li>
                <li style="color:#007FFF">
                  <b>21/06/2020</b> Vertical toolbar.<br>
                  Vertical toolbar is automatically enabled on wide devices. Can be enabled and disabled on all devices from the settings menu.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>20/06/2020</b>: Removed teams with duplicate heroes (SC Hero + Normal hero) & other minor functions!<br>
                  Removed teams that contain the same hero twice like Lorina and Commander Lorina. If you lock SC character and he's normal version you will get an error.<br>
                  You can cancel from results calculation if it's taking too long and you don't want to wait.<br>
                  Now you can quickly select your heroes in "Multi-lock".
                </li>
                <li style="color:rgb(0, 148, 32)">
                  <b>15/06/2020</b>: Faster calculation formula for large rosters!<br>
                  Doesn't support advanced settings, if advanced settings are active the old formula will be used to calculate the results".<br>
                  Can be improved with more checks. Maybe...<br>
                  New "{{strings.add_displayed_heroes}}" and "{{strings.remove_displayed_heroes}}" functions to quickly add and remove heroes while testing teams.
                </li>
                <li style="color:rgb(255, 60, 0)">
                  Add Most saved teams statistics!<br>
                  Select the cog icon in the toolbar -> "{{strings.most_saved_teams}}".
                </li>
                <li style="color:rgb(0, 148, 32)">
                  Now you can select the number of results or minimum morale to be displayed.<br>
                  Instructions: Select "Advanced settings" => click on the cog icon on the top left of the page => check "{{strings.numero_massimo_risultati}}" or/and "{{strings.morale_minimo_risultati}}" then type in the desired number in the corresponding input field.<br>
                  Please don't set a high number in the "{{strings.numero_massimo_risultati}}" input field or too low in "{{strings.morale_minimo_risultati}}" as your browser may slow down while displaying to many results.
                  By default (or if you don't provide a number) top 200 results are displayed.
                </li>
                <li style="color:#007FFF">
                  New: "Generate URL"<br>
                  Select this option in the settings window to generate a URL containing a copy of your current roster.<br>
                  You can use that URL on any device.<br>
                  If you open this tool with a generated URL it will replace your local roster on that device.<br>
                  You don't need a URL to save your roster. Your roster is automatically saved on your device, the URL is useful if you need to transfer you roster to a different device so you don't have to manually add each hero.
                </li>
                <li style="color:#007FFF">
                  New setting option "Debug: Display camping values"<br>
                  When enabled you can right click (or long tap on mobile) on a hero's portrait to view that character's camping values.<br>
                  Useful if you want to check if the data is correct or updated.
                </li>
                <li>
                  Default language is now autodetected during first boot.<br>
                  You can change language in the settings.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  Now you can select German, Portoguese, French and Spanish as language.<br>
                  Only French has gamedata and menus translated. Thanks again to <a href="https://www.reddit.com/user/TriATK/">TriATK</a> for the translation.<br>
                  DE, ES and PT have only gamedata translated (Character name, Camping topics, buffs and debuffs) if you want to help translate the menus contact me.<br>
                  By default ENG is selected to change language go to Settings.
                </li>
                <li style="color:rgb(0, 148, 32)">
                  Added Japanese, Chinese (S) and Korean languages:<br>
                  Japanese and Korean are missing menu translation but game data is translated, Chinese (S) has full translation menus + game data.<br>
                  Thanks to <a href="https://www.reddit.com/user/TriATK/">TriATK</a> for the Chinese translation.<br>
                  By default ENG is selected to change language go to Settings.
                </li>
                <li>
                  Added Notifications in settings:<br>
                  Enable to recive a notification when the page is done calculating results.<br>
                  This function is useful if you are on PC and have a large roster, this page will only sand the notification if the page is in background and will not send you any other kind of notification!
                </li>
                <li style="color:rgb(0, 148, 32)">
                  Added Multi-lock:<br>
                  Add your heroes to one of the 4 slots (each slot is a space in your team), if you add 2 or more heroes into the same slot only one of them will be in each team!
                </li>
                <li style="color:#007FFF">
                  Now you can save your results:<br>
                  In the results window tap/click <i class="fa fa-save" aria-hidden="true"></i>  , in the modal window type a name for that specific camp and click "Save".<br>
                  Your saved camps will appear in the <i class="fa fa-cog" aria-hidden="true"></i>  settings window where you can view and delete them.
                </li>
                <li>
                  At boot a web worker will be generated and will handle team calculations, this will prevent your browser from displaying the message "This page is not responding".<br>
                  This tool can calculate all 35.208.615 possible combinations without crashing (it has low RAM usage during calculation) but it will require a long time (13-17 minutes, locking a hero 20 seconds);
                </li>
              </ul>
            </div>
            <div id="instructions_content" style="display: none; text-align: center; margin-top: 10%;">
              Quick guide:
              <div style="padding-top: 30px;">
                <i class="fa fa-plus" aria-hidden="true"></i>: Add heroes to your roster.<br><br>
                <i class="fa fa-pencil-alt" aria-hidden="true"></i>: Check your roster. Lock a hero by clicking on the portrait or remove it by clicking the <font color="red">x</font> symbol near the portrait.<br><br>
                <i class="fa fa-book" aria-hidden="true"></i> (optional): Set custom rules to find the best team for your needs. (Enabling advanced settings is slower for large rosters)<br><br>
                <i class="fas fa-fire" aria-hidden="true"></i>Click the campfire icon to find all possible combinations for your roster. (You need at least 4 heroes in your roster)<br><br>
                <i class="fa fa-question-circle" aria-hidden="true"></i>: You can find this icon near the title of each page. On click it will display some instructions for that page.<br><br>
                <i class="fa fa-cog"></i>: Change settings for the website.<br>
              </div>
            </div>
            <div id="cool_websites_content" style="display: none; text-align: center; margin-top: 10%;">
              Cool websites you should check out:
              <p><a href="https://epicsevendb.com/">EpicSevenDB</a> by RaphaelDDL</p>
              <p><a href="https://e7herder.com/">E7herder</a> with a cool model viewer</p>
              <p><a href="https://maphe.github.io/e7-damage-calc/">Epic 7 Damage Calculator</a> by Maphe</p>
              <p><a href="https://www.e7leaks.com/">Epic 7 Leaks</a> by Maphe</p>
              <p><a href="https://epic7pvp.com">Epic7pvp.com</a> for PVP community events</p>
              <p><a href="https://meowyih.github.io/epic7-gear/index.html?lang=en">Web tool to evaluate gears</a> by meowyih</p>
              <p><a href="http://www.epicseventools.com/Home/LabMoraleOptimizer">E7 Tools</a> by Budandan</p>
              <p><a href="https://gamepress.gg/epicseven/">GamePress.gg</a></p>
            </div>
            <div id="credits_content" style="display: none;">
              <div style="position: absolute; bottom: 10%; text-align: center; right: 0; left: 0;">
                <br>ENG Hell raid map: <a href="https://www.reddit.com/user/C0NNECT1NG/">u/C0NNECT1NG</a> (<a href="https://www.reddit.com/r/EpicSeven/comments/flg4b1/complete_hell_raid_map/">Reddit post</a>)
                <br>Normal and Chinese Hell raid map: TriATK
                <br>Chinese/French translations: TriATK
                <br>Contact me: <a href="https://www.reddit.com/user/UsernameSniped/">u/UsernameSniped</a>
                <br>Discord: gio#0898
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>
    <!--WELCOME WINDOW END-->

    <!--ADD HEROES WINDOW-->
    <div id="add_window" style="display:none;">
      <h2><span style="position:relative;top:10px;vertical-align: middle">{{strings.aggiungi}} <i class="fa fa-question-circle" aria-hidden="true" style="font-size:20px; cursor: pointer;" v-on:click="helpWindow('add_window', 'add_heroes_help')"></i></span>
        <div style="display: inline-block;">
          <input type="text" id="inputInTuttiGliEroi" class="search_hero_filter searchBox" onkeyup="app.filtroTuttiGliEroi({tipo:'input',casella:this,value:this.value,className: 'search_hero_filter', name: 'ricerca'})" v-bind:placeholder="strings.search+'...'" title="Type in a name">
          <button class="search_input"><i class="fa fa-search" aria-hidden="true"></i></button>
        </div>
	    </h2>
       <!-- Pulsanti filtro eroi -->
      <div style="display:inline-block;width:100%;">
        <div class="search_hero_area" id="filter_all_rarity">
          <button class="search_hero_filter active" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this)" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this)" value="3">
            <div><i>3</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button><!-- 
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this)" value="4">
            <div><i>4</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button><!-- 
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this)" value="5">
            <div><i>5</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button>
        </div>
        <div class="search_hero_area">
          <button class="search_hero_filter active" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="fire">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_profire.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="ice">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_proice.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="wind">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_proearth.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="light">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_prolight.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this)" value="dark">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_promdark.png">
          </button>
        </div>
        <div class="search_hero_area">
          <button class="search_hero_filter active" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="knight">
            <!-- <span>knight</span> -->
          <img src="https://assets.epicsevendb.com/class/cm_icon_role_knight.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="warrior">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_warrior.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="assassin">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_thief.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="ranger">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_ranger.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="mage">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_mage.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this)" value="manauser">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_soul-weaver.png">
          </button>
        </div>
        <!--
        <div class="search_hero_area">
          <button class="search_hero_filter" name="filter_gia_aggiunti" onclick=app.filtroTuttiGliEroi(this) value="false">
            <div style="max-height:20px;"><i class="fa fa-eye"></i></div>
          </button>--><!--
          --><!--<button class="search_hero_filter active" name="filter_gia_aggiunti" onclick=app.filtroTuttiGliEroi(this) value="true">
            <div style="max-height:20px;"><i class="fa fa-eye-slash"></i></div>
          </button>
        </div>-->
        <div class="search_hero_area dropdown">
          <button id="allHeroes_sort_by" class="search_hero_filter" onmouseover="document.getElementById('dropdown_allHeroes_sort_by').style.removeProperty('display')" style="font-size:16px; width:90px;" name="sort_by" value="name">{{strings.sort}}</button>
          <div id="dropdown_allHeroes_sort_by" class="dropdown-content" style="float:right;">
            <div class="active" onclick="app.databaseSort='name'; this.parentElement.style.display='none'">{{strings.name}}</div>
            <div class="active" onclick="app.databaseSort='rarity'; this.parentElement.style.display='none'">{{strings.rarity}}</div>
            <div class="active" onclick="app.databaseSort='attribute'; this.parentElement.style.display='none'">{{strings.attribute}}</div>
            <div class="active" onclick="app.databaseSort='role'; this.parentElement.style.display='none'">{{strings.classe}}</div>
            <div class="active" onclick="app.databaseSort='id'; this.parentElement.style.display='none'">{{strings.ingame_id}}</div>
            <div class="active dropdown" onclick="var x = this.getBoundingClientRect().right; if (document.body.getBoundingClientRect().right-x>320)document.getElementById('dropdown_sort_by_topic').style.left='100%'; else document.getElementById('dropdown_sort_by_topic').style.left='-200%'" onmouseover="document.getElementById('dropdown_sort_by_topic').style.removeProperty('display')">{{strings.topics}}
              <span style="float:right">></span>
              <div id="dropdown_sort_by_topic" class="dropdown-content" style="top:-500%;left:100%; width:320px">
                <div v-for="t in ['Advice','Faith','Bizarre Story','Comforting Cheer','Complain','Criticism','Cute Cheer','Dream','Food Story','Gossip','Happy Memories','Heroic Cheer','Heroic Tale','Horror Story','Interesting Story','Joyful Memory','Myth','Occult','Reality Check','Sad Memory','Self-Indulgent','Unique Comment']"
                 class="active" 
                 v-on:click="databaseSort=['c_values',t]"
                 onclick="this.parentElement.style.display='none'"
                 style='display: inline-block; width: 50%; box-sizing: border-box;'
                >
                  {{translateTopics(t)}}
                </div>
              </div>
            </div>
          </div>
        </div>
        <button class="search_hero_area search_hero_filter" v-on:click="alertUserAction('addDisplayed');" style="margin-right: 30px; width: auto; font-size: 16px; font-size:16px; width:90px; width: auto;">{{strings.add_displayed_heroes}}</button>
        <div id="pulsanti_display_add_window" class="search_hero_area" style="display:inline-block">
          <button class="search_hero_filter active" name="display_list" onclick="app.setDisplayStyle(this, 'add_window')" value="grid">
            <div><i class="fa fa-th-large"></i></div>
          </button><!--
          --><button class="search_hero_filter" name="display_list" onclick="app.setDisplayStyle(this, 'add_window')" value="list">
            <div><i class="fa fa-th-list"></i></div>
          </button>
         </div>
      </div>
      <!-- fine pulsanti filtro eroi -->

      <!-- display tutti gli eroi -->
       <template v-if="displayStyle === 'grid'"> <!-- grid -->
        <table id="lista_hero_disponibili">
          <tr>
            <td style="text-align: center; padding-bottom: 20px;">
              <hero-icon v-for="key in sortedHeroDB" v-show="displayList.includes(key)" :data="thisHeroData(key)" @clicked="addHero(thisHeroData(key)._id)" @contextmenu="rightClickHero(key, $event)" :img="getHeroAssets(key).icon" :displayname="avatars.name" :name="thisHeroTranslatedName(key)" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="parseFloat(avatars.scale)" :hoverable="avatars.hoverable" v-bind:style="'opacity:' + (myHeroesList[key] ? 0.5 : 1) "></hero-icon>
            </td>
          </tr>
         </table>
	      </template>
        <template v-else-if="displayStyle === 'list'">  <!-- Lista -->
         <table class="displaylistTable" style="margin-left:auto;margin-right:auto;">
          <tr v-for="key in sortedHeroDB" v-if="displayList.includes(key)">
            <td>
              <div class="hero_potrait" @contextmenu="rightClickHero(key, $event)">
                <img v-bind:src="getHeroAssets(key).icon" onerror="this.onerror=null; this.src=app.getHeroAssets(this.alt, 'onerror').icon" style="width:70px;vertical-align: middle;top:15px;" v-on:click="addHero(thisHeroData(key)._id)" v-bind:alt="thisHeroData(key)._id" v-bind:titolo="thisHeroData(key).name"/>
		            <span>{{ thisHeroTranslatedName(thisHeroData(key)._id) }}</span>
		            <template v-if="!isInTeam(thisHeroData(key)._id)">  <!-- già aggiunto -->
                  <span v-on:click="addHero(thisHeroData(key)._id)" class="fa fa-plus displaylistTableIcons">   </span>
                </template>
		            <template v-else> <!-- aggiungi -->
                  <span class="fa fa-check-circle displaylistTableIcons"></span>
                </template>
              </div>
            </td>
          </tr>
         </table>
        </template>
    </div>

    <div id="manage_window" style="display:none;">
      <h2>
        <span style="position:relative;top:10px;vertical-align: middle">{{strings.i_tuoi_eroi}}
          <span style="display: inline-block; background: rgb(250,0,80); border-radius: 4px; min-width: 40px; height: 25px; padding: 4px; text-align: center; color: white; font-size: 20px;">{{rosterLength}}</span>
          <i class="fa fa-question-circle" aria-hidden="true" style="font-size:20px; cursor: pointer;" v-on:click="helpWindow('manage_window', 'manage_heroes_help')"></i> 
        </span>
          <div style="display: inline-block;">
            <input type="text" id="inputInMyHeroes" class="search_hero_filter searchBox" onkeyup="app.filtroTuttiGliEroi({tipo:'input',casella:this,value:this.value,className: 'search_hero_filter', name: 'ricerca'}, 'MyHeroes')" v-bind:placeholder="strings.search+'...'" title="Type in a name">
            <button class="search_input"><i class="fa fa-search" aria-hidden="true"></i></button>
          </div>
          <!--
          <template v-if="locked.length>0">
            <button class="search_hero_filter" style="display: inline-block; background: rgb(250, 0, 80); border-radius: 4px; border: double; width: auto; min-width: 40px; padding: 8px; text-align: center; color: white; font-size: 20px;" name="filter_rarity" v-on:click="document.getElementById('calculate_window').style.display =''; document.getElementById('manage_window').style.display ='none'; isLoadingResults = true; risultati = []; var tmp = Object.keys(HeroDB); for (var i=0; i<locked.length;i++) tmp.splice(tmp.indexOf(locked[i]), 1); camperino.postMessage({HeroDB: HeroDB, myHeroesList: HeroDB, campList: tmp, locked: locked, classe: [], elemento: [], debuffs: [], buffs: [], AoE: false, noS1debuffs: false, noDebuffs: false, cartesianLock: [[],[],[],[]], preferenzeRisultati: customizedResuts, risultati: []});">
              Variations
            </button>
          </template>
          -->
	    </h2>
       <!-- Pulsanti filtro eroi -->
      <div style="display:inline-block;width:100%;">
        <div class="search_hero_area" id="filter_myHeroes_rarity">
          <button class="search_hero_filter active" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="3">
            <div><i>3</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button><!-- 
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="4">
            <div><i>4</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button><!-- 
          --><button class="search_hero_filter" name="filter_rarity" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="5">
            <div><i>5</i><img src="https://assets.epicsevendb.com/star/cm_icon_star.png" /></div>
          </button>
        </div>
        <div class="search_hero_area">
          <button class="search_hero_filter active" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="fire">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_profire.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="ice">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_proice.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="wind">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_proearth.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="light">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_prolight.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_element" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="dark">
            <img src="https://assets.epicsevendb.com/attribute/cm_icon_promdark.png">
          </button>
        </div>
        <div class="search_hero_area">
          <button class="search_hero_filter active" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="*">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="knight">
            <!-- <span>knight</span> -->
          <img src="https://assets.epicsevendb.com/class/cm_icon_role_knight.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="warrior">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_warrior.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="assassin">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_thief.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="ranger">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_ranger.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="mage">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_mage.png">
          </button><!-- 
          --><button class="search_hero_filter" name="filter_class" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="manauser">
            <img src="https://assets.epicsevendb.com/class/cm_icon_role_soul-weaver.png">
          </button>
        </div>
        <div class="search_hero_area">
          <button class="search_hero_filter active" name="filter_locked_only" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="false">
            <div style="font-size:16px">{{strings.all}}</div>
          </button><!--
          --><button class="search_hero_filter" name="filter_locked_only" onclick="app.filtroTuttiGliEroi(this, 'MyHeroes')" value="true"> <!-- di default nascondi eroi già aggiunti -->
            <div style="max-height:20px;"><i class="fa fa-lock"></i></div>
          </button>
        </div>
        <div class="search_hero_area dropdown">
          <button id="myHeroes_sort_by" class="search_hero_filter" onmouseover="document.getElementById('dropdown_sort_myHeroes').style.removeProperty('display')" style="font-size:16px; width:90px;" name="sort_by" value="date">{{strings.sort}}</button>
          <div id="dropdown_sort_myHeroes" class="dropdown-content" style="float:right;">
            <div class="active" onclick="app.rosterSort='date'; this.parentElement.style.display='none'">{{strings.modified}}</div>
            <div class="active" onclick="app.rosterSort='name'; this.parentElement.style.display='none'">{{strings.name}}</div>
            <div class="active" onclick="app.rosterSort='rarity'; this.parentElement.style.display='none'">{{strings.rarity}}</div>
            <div class="active" onclick="app.rosterSort='attribute'; this.parentElement.style.display='none'">{{strings.attribute}}</div>
            <div class="active" onclick="app.rosterSort='role'; this.parentElement.style.display='none'">{{strings.classe}}</div>
            <div class="active" onclick="app.rosterSort='id'; this.parentElement.style.display='none'">{{strings.ingame_id}}</div>
            <div class="active dropdown" onclick="var x = this.getBoundingClientRect().right; if (document.body.getBoundingClientRect().right-x>320)document.getElementById('dropdown_sort_by_topic_b').style.left='100%'; else document.getElementById('dropdown_sort_by_topic_b').style.left='-200%'" onmouseover="document.getElementById('dropdown_sort_by_topic_b').style.removeProperty('display')">{{strings.topics}}
              <span style="float:right">></span>
              <div id="dropdown_sort_by_topic_b" class="dropdown-content" style="top:-600%;left:100%; width:320px">
                <div v-for="t in ['Advice','Faith','Bizarre Story','Comforting Cheer','Complain','Criticism','Cute Cheer','Dream','Food Story','Gossip','Happy Memories','Heroic Cheer','Heroic Tale','Horror Story','Interesting Story','Joyful Memory','Myth','Occult','Reality Check','Sad Memory','Self-Indulgent','Unique Comment']"
                 class="active" 
                 v-on:click="rosterSort=['c_values',t]"
                 onclick="this.parentElement.style.display='none'"
                 style='display: inline-block; width: 50%; box-sizing: border-box;'
                >
                  {{translateTopics(t)}}
                </div>
              </div>
            </div>
          </div>
        </div>
        <button class="search_hero_area search_hero_filter" v-on:click="alertUserAction('removeDisplayed');" style="margin-right: 30px; width: auto; font-size: 16px; font-size:16px; width:90px; width: auto;">{{strings.remove_displayed_heroes}}</button>
        <div id="pulsanti_display_manage_window" class="search_hero_area" style="display:inline-block"> <!-- Grid/List buttons-->
          <button class="search_hero_filter active" name="display_list" onclick="app.setDisplayStyle(this, 'manage_window')" value="grid">
            <div><i class="fa fa-th-large"></i></div>
          </button><!--
          --><button class="search_hero_filter" name="display_list" onclick="app.setDisplayStyle(this, 'manage_window')" value="list">
            <div><i class="fa fa-th-list"></i></div>
          </button>
        </div>
      </div>
      <!-- fine pulsanti filtro eroi -->

       <template v-if="displayStyle === 'grid'">  <!-- grid -->
        <table id="myHeroes">
          <tr>
            <td style="text-align: center; padding-bottom: 20px;">
              <hero-icon v-for="key in roster" v-show="displayMyHeroes.includes(key)" v-bind:data="thisHeroData(key)" @clicked="lockHero(key)" @remove="removeHero(key)" @contextmenu="rightClickHero(key, $event)" :img="getHeroAssets(key).icon" :removable="true" :displayname="avatars.name" :name="thisHeroTranslatedName(key)" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="parseFloat(avatars.scale)" :hoverable="avatars.hoverable" :selected="isLocked(key)"></hero-icon>
            </td>
          </tr>
        </table>
      </template>
      <template v-else-if="displayStyle === 'list'">  <!-- Lista -->
        <table id="myHeroes" class="displaylistTable" style="margin-left:auto;margin-right:auto;">
         <tr v-for="key in roster" v-if="displayMyHeroes.includes(key)">
           <td>
             <div class="hero_potrait" @contextmenu="rightClickHero( key, $event)">
               <img v-bind:src="getHeroAssets(key).icon" onerror="this.onerror=null; this.src=app.getHeroAssets(this.alt, 'onerror').icon" style="width:70px;vertical-align: middle;top:15px;" v-on:click="addHero(thisHeroData(key)._id)" v-bind:alt="thisHeroData(key)._id" v-bind:titolo="thisHeroData(key).name"/>
                <span>{{ thisHeroTranslatedName(thisHeroData(key)._id) }}</span>
                <span v-on:click="app.removeHero(thisHeroData(key)._id)" class="fa fa-trash displaylistTableIcons" aria-hidden="true"></span>
                <template v-if="!isLocked(thisHeroData(key)._id)">  <!-- non lockato -->
                  <span class="fa fa-unlock-alt displaylistTableIcons" v-on:click="app.lockHero(thisHeroData(key)._id)"></span>
                </template>
                <template v-else> <!-- simbolo lock -->
                  <span class="fa fa-lock displaylistTableIcons" style="color:blue;" v-on:click="app.lockHero(thisHeroData(key)._id)"></span>
                </template>
             </div>
           </td>
         </tr>
        </table>
      </template>
    </div>

    <div id="advanced_window" style="display:none;">
      <div v-if="rosterLength>69 && locked.length===0" style="background-color: #fff27dBF;padding: 10px;border-radius: 4px;text-align: center;color: black;">
        <p style="margin:0 0 8px 0"><b>{{ strings.warn_tsize_adv_title }}</b></p>
        <p style="margin: 0; white-space: pre-wrap; font-size: 15px;">{{ strings.warn_tsize_adv_details }}</p>
      </div>
      <h2>{{strings.impostazioni_avanzate}}  <i class="fa fa-question-circle" aria-hidden="true" style="font-size:20px; cursor: pointer;" v-on:click="helpWindow('advanced_window', 'advanced_settings')"></i></h2>
      <div style="float: right; position: relative; z-index: 1;">
        <button class="search_hero_filter" onclick="document.getElementById('impostazioni_risultati').style.display='block'" style="font-size:16px; width:70px;" name="sort_by"><i class="fa fa-cog" aria-hidden="true"></i></button>
        <div id="impostazioni_risultati" class="dropdown-content" style="right: 32px; z-index: 2;">
          <span>
            <label class="check">
              <input type="checkbox" id="numeroRisultatiMassimo" name="numeroRisultatiMassimo" onclick="app.personalizzaRisultati()">
              <span class="checkmark"></span>
              {{strings.numero_massimo_risultati}}
              <input style="display: inline-block; width: 100px; height: 20px" type="number" min="1" id="n_risultati" onkeyup="app.personalizzaRisultati()" placeholder="default 200" title="Number of results" disabled>
            </label>
          </span>
          <span>
            <label class="check">
              <input type="checkbox" id="moraleMinimo" name="moraleMinimo" value="moraleMinimo" onclick="app.personalizzaRisultati()">
              <span class="checkmark"></span>
              {{strings.morale_minimo_risultati}}
              <input style="display: inline-block; width: 100px; height: 20px" type="number" min="0" max="52" id="n_moraleMinimo" onkeyup="app.personalizzaRisultati()" placeholder="0 - 52" title="Min morale" disabled>
            </label>
          </span>
          <span>
            <label class="check" style="width: 95%">
              <input type="checkbox" id="includi_locked_in_advanced_settings" onclick="app.personalizzaRisultati()">
              <span class="checkmark"></span>
              {{strings.includi_locked_in_adv}}
            </label>
          </span>
          <span>
            <label class="check" style="width: 95%">
              <input type="checkbox" id="adv_mute_locked_heroes" onclick="app.personalizzaRisultati()">
              <span class="checkmark"></span>
              {{strings.adv_mute_locked_heroes}}
            </label>
          </span>
          <b class="close" style="right: 10px;" onclick="document.getElementById('impostazioni_risultati').style.display='none'">×</b>
        </div>
      </div>
      <label class="check">
        <input type="checkbox" id="AoE" name="AoE" value="AoE" onclick="app.aggiornaImposatazioniAvanzate()">
        <span class="checkmark"></span>
        {{strings.deve_contenere_AoE}}
      </label>
      <label class="check">
        <input type="checkbox" id="noS1debuffs" name="noS1debuffs" value="noS1debuffs" onclick="app.aggiornaImposatazioniAvanzate()">
        <span class="checkmark"></span>
        {{strings.no_s1_debuffs}}
      </label>
      <label class="check">
        <input type="checkbox" id="noDebuffs" name="noDebuffs" value="noDebuffs" onclick="app.aggiornaImposatazioniAvanzate()">
        <span class="checkmark"></span>
        {{strings.no_debuffs}}
      </label>
      <label class="check">
        <input type="checkbox" id="mustIncludeDispel" name="mustIncludeDispel" value="mustIncludeDispel" onclick="app.aggiornaImposatazioniAvanzate()">
        <span class="checkmark"></span>
        {{strings.must_include_dispel}}
      </label>
      <label class="check" style="display: none;">
        <input type="checkbox" id="mustIncludeCleanser" name="mustIncludeCleanser" value="mustIncludeCleanser" onclick="app.aggiornaImposatazioniAvanzate()">
        <span class="checkmark"></span>
        {{strings.must_include_cleanser || 'missing(strings.must_include_cleanser)'}}
      </label>
      <div id="advanced_classe" class="box_advanced_settings" style="height:auto;width:100%;display:inline-block;padding-bottom: 25px;padding-top: 5px;">
        <center>{{strings.classe}}:</center>
          <div class="adv_settings_elem noselect" v-for="(value,key) in {
                    knight: {string: strings['knight'], icon: 'cm_icon_role_knight'}, 
                    assassin: {string: strings['thief'], icon: 'cm_icon_role_thief'}, 
                    warrior: {string: strings['warrior'], icon: 'cm_icon_role_warrior'}, 
                    ranger: {string: strings['ranger'], icon: 'cm_icon_role_ranger'}, 
                    mage: {string: strings['mage'], icon: 'cm_icon_role_mage'},
                    manauser: {string: strings['soul-weaver'], icon: 'cm_icon_role_soul-weaver'},
                  }
          " >
            <div class="class-quantity-container" v-bind:value="key">
              <span class="quantity_curr_quantity" style="display: none;">
              </span>
              <span class="incrementa" onclick="app.editClassQuantity(this)">
                +
              </span>
              <span class="decrementa" onclick="app.editClassQuantity(this)">
                -
              </span>
            </div>
            <img v-bind:src="'https://assets.epicsevendb.com/class/' + value.icon + '.png'" style="height:60px;width:60px;" />
            <p style="position:relative;text-align:center;">{{value.string}}</p>
          </div>
      </div>
      <br><br>
      <div id="advanced_elemento" class="box_advanced_settings" style="height:auto;width:100%;display:inline-block;padding-bottom: 25px;padding-top: 5px;">
        <center>{{strings.classe}}:</center>
          <div class="adv_settings_elem noselect" v-for="(value,key) in {
                    fire: {string: strings['fire'], icon: 'cm_icon_profire'}, 
                    ice: {string: strings['ice'], icon: 'cm_icon_proice'}, 
                    wind: {string: strings['earth'], icon: 'cm_icon_proearth'}, 
                    light: {string: strings['light'], icon: 'cm_icon_prolight'}, 
                    dark: {string: strings['dark'], icon: 'cm_icon_promdark'}
                  }
          " >
            <div class="class-quantity-container" v-bind:value="key">
              <span class="quantity_curr_quantity" style="display: none;">
              </span>
              <span class="incrementa" onclick="app.editAttributeQuantity(this)">
                +
              </span>
              <span class="decrementa" onclick="app.editAttributeQuantity(this)">
                -
              </span>
            </div>
            <img v-bind:src="'https://assets.epicsevendb.com/attribute/' + value.icon + '.png'" style="height:60px;width:60px;" />
            <p style="position:relative;text-align:center;">{{value.string}}</p>
          </div>
      </div>
      <br><br>
      <div id="advanced_buff" class="box_advanced_settings" style="height:auto;width:100%;display:inline-block;padding-bottom: 25px;padding-top: 5px;">
        <center>{{strings.buff}}:</center>
        <span v-for="(value,key) in buffList" style="display:inline-block;position:relative;top:0px;text-align:center;height:auto;width:120px;padding-bottom:5px;">
          <input type="checkbox" v-bind:id="'checkbox_'+ key" name="buff" v-bind:value="value.id" style="position:relative;top:0px;display:none" onclick="app.aggiornaImposatazioniAvanzate()">
          <label v-bind:for="'checkbox_'+ key" class="label noselect" style="position:relative;top:0px;"> <img v-bind:src="'https://assets.epicsevendb.com/buff/' + key + '.png'" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">{{value.name}}</p></label>
        </span>
      </div>
      <br><br>
      <div id="advanced_debuff" class="box_advanced_settings" style="height:auto;width:100%;display:inline-block;padding-bottom: 25px;padding-top: 5px;">
        <center>{{strings.debuff}}:</center>
        <span v-for="(value,key) in debuffList" style="display:inline-block;position:relative;top:0px;text-align:center;height:auto;width:120px;padding-bottom:5px;">
          <input type="checkbox" v-bind:id="'checkbox_'+ key" name="debuff" v-bind:value="value.id" style="display:none" onclick="app.aggiornaImposatazioniAvanzate()">
          <label v-bind:for="'checkbox_'+ key" class="label noselect" style="position:relative;top:0;"> <img v-bind:src="'https://assets.epicsevendb.com/buff/' + key + '.png'" style="position:relative;top:0;height:60px;width:60px;" /><p style="position:relative;text-align:center;">{{value.name}}</p></label>
          </span>
      </div>
      <br><br>
      <div id="advanced_cartesian" class="box_advanced_settings" style="height:auto;width:100%;display:inline-block;padding-bottom: 25px;padding-top: 5px;">
        <center>{{strings.multilock}}<i class="fa fa-question-circle" aria-hidden="true" style="font-size:20px; cursor: pointer;" v-on:click="helpWindow('advanced_window', 'multi-lock')"></i></center>
        <div v-for="(key,index) in cartesian_lock" style="display:inline-block;margin:20px;width:22%;min-width:230px">
          {{strings.multilock_slot}} {{index+1}}
          <button type="button" v-on:click="openCartesianLock(index)" class="button_login">{{strings.add_to_slot}}</button>
          <div style="height:300px;max-height:300px;background-color:var(--bg-color);display:block;color:var(--font-color);overflow-x:scroll;overflow-x: hidden;padding-left:10px;padding-top:10px;padding-right:10px;">
            <span v-for="(key,i) in cartesian_lock[index]" style="display:inline-block;position:relative;width:100%">{{thisHeroTranslatedName(thisHeroData(key)._id)}}<span class="removecartesian" style="position:relative;float:right;font-size:16px;" v-on:click="removeCartesian_lock(index, key)">X</span></span>
          </div>
        </div>
      </div>
    </div>

    <div id="calculate_window" class="center" style="display:none;">
      <h2>{{strings.risultati}}  <i class="fa fa-question-circle" aria-hidden="true" style="font-size:20px; cursor: pointer;" v-on:click="helpWindow('calculate_window', 'results_help')"></i></h2>
      <table>
        <thead>
          <th></th>
          <th colspan="4">{{strings.team}}</th>
          <th>{{strings.topics}}</th>
          <th style="white-space: nowrap;">{{strings.morale}}</th>
        </thead>
        <tbody>
          <tr v-for="(item, index) in risultati.slice((currentResultsPage-1)*25,(currentResultsPage-1)*25+25)">
            <td width="4%" style="padding-top: 30px;padding-bottom: 30px;text-align: center; cursor: pointer;" v-on:click="mostraSalvaRisultato(index+(currentResultsPage-1)*25)"><i class="fa fa-save" aria-hidden="true" style="font-size:30px;"></i>
              <br>{{index+1+(currentResultsPage-1)*25}}</td>
            <td class="hero_potrait" style="max-width: 100px;">
              <hero-icon v-bind:data="thisHeroData(item.team[0])" @contextmenu="rightClickHero(item.team[0], $event)" :img="getHeroAssets(item.team[0]).icon" :hoverable="false" :displayname="avatars.name" :name="thisHeroTranslatedName(item.team[0])" :showstars="avatars.stars" :role_attr="avatars.role_attr" :size="60" :scale="parseFloat(avatars.scale)" class="imgResults"></hero-icon>
            </td>
            <td class="hero_potrait" style="max-width: 100px;">
              <hero-icon v-bind:data="thisHeroData(item.team[1])" @contextmenu="rightClickHero(item.team[1], $event)" :img="getHeroAssets(item.team[1]).icon" :hoverable="false" :displayname="avatars.name" :name="thisHeroTranslatedName(item.team[1])" :showstars="avatars.stars" :role_attr="avatars.role_attr" :size="60" :scale="parseFloat(avatars.scale)" class="imgResults"></hero-icon>
            </td>
            <td class="hero_potrait" style="max-width: 100px;">
              <hero-icon v-bind:data="thisHeroData(item.team[2])" @contextmenu="rightClickHero(item.team[2], $event)" :img="getHeroAssets(item.team[2]).icon" :hoverable="false" :displayname="avatars.name" :name="thisHeroTranslatedName(item.team[2])" :showstars="avatars.stars" :role_attr="avatars.role_attr" :size="60" :scale="parseFloat(avatars.scale)" class="imgResults"></hero-icon>
            </td>
            <td class="hero_potrait" style="max-width: 100px;">
              <hero-icon v-bind:data="thisHeroData(item.team[3])" @contextmenu="rightClickHero(item.team[3], $event)" :img="getHeroAssets(item.team[3]).icon" :hoverable="false" :displayname="avatars.name" :name="thisHeroTranslatedName(item.team[3])" :showstars="avatars.stars" :role_attr="avatars.role_attr" :size="60" :scale="parseFloat(avatars.scale)" class="imgResults"></hero-icon>
            </td>
            <td class="topics"><b>{{thisHeroTranslatedName(thisHeroData(item.migliorPG1)._id)}}</b>: <a>{{translateTopics(item.opzioneMigliore1)}}</a><br><b>{{thisHeroTranslatedName(thisHeroData(item.migliorPG2)._id)}}</b>: <a>{{translateTopics(item.opzioneMigliore2)}}</a></td>
            <td style="text-align:center; font-family:sans-serif;font-size:17px" width="3%">{{item.morale}}</td>
          </tr>
        </tbody>
      </table>
      <pagination
        :total-pages="Math.ceil( risultati.length/25 )"
        :total="risultati.length"
        :per-page="25"
        :current-page="currentResultsPage"
        @pagechanged="changeResultsPage"
      />
    </div>

    <div id="extras_window" style="display:none;height: 100%;">
      <div id="extras_menu" class="extras_grid" style="margin-top: 5%">
        <div class="extra_icon box_advanced_settings" onclick="setWindow('settings_window')">
          <span>
            <i class="fa fa-cog" style="font-size: 90px;"></i><br><br>
            {{strings.impostazioni}}
          </span>
        </div>
        <div class="extra_icon box_advanced_settings" onclick="setWindow('my_teams_window')">
          <span>
            <i class="fa fa-save" aria-hidden="true" style="font-size:90px;"></i><br><br>
            {{strings.my_teams}}
          </span>
        </div>
        <div class="extra_icon box_advanced_settings" onclick="setWindow('raid_map')">
          <span>
            <i class="fa fa-map" aria-hidden="true" style="font-size:90px;"></i><br><br>
            {{strings.extras_map}}
          </span>
        </div>
        <div class="extra_icon box_advanced_settings" onclick="setWindow('saved_teams_stats');app.computedGetSavedTeamsStats;">
          <span>
            <i class="fa fa-chart-bar" aria-hidden="true" style="font-size:90px;"></i><br><br>
            {{strings.most_saved_teams}}
          </span>
        </div>
      </div>
    </div>
    <div id="settings_window" style="display:none;">
      <h2>{{strings.impostazioni}}</h2><br>
      <table class="displaylistTable" style="margin-left:auto;margin-right:auto;">
        <tr>
          <td>
            <div style="max-height:55px">
              <span>
                {{strings.tema_notturno}}
              </span>
              <i style="font-size:38px;float: right;padding:10px;position:relative;top:0px;right:60px;">
                <label class="switch" style="position:absolute;">
                  <input type="checkbox" id="darkModeCheck" name="darkModeCheck" onchange="toggleCheck()">
                  <i class="slider round"></i>
                </label>
              </i>
            </div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="max-height:55px">
              <span>
                {{strings.notifiche}}
              </span>
              <i style="font-size:38px;float: right;padding:10px;position:relative;top:0px;right:60px;">
                <label class="switch" style="position:absolute;">
                  <input type="checkbox" id="notifications_toggle" name="notifications_toggle" onchange="askNotificationPermission()">
                  <i class="slider round"></i>
                </label>
              </i>
            </div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="max-height:55px">
              <span>
                {{strings.vert_iconbar}}
              </span>
              <i style="font-size:38px;float: right;padding:10px;position:relative;top:0px;right:60px;">
                <label class="switch" style="position:absolute;">
                  <input type="checkbox" id="toolbar_position" name="toolbar_position" onchange="toggleVerticalToolbar()">
                  <i class="slider round"></i>
                </label>
              </i>
            </div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="max-height:55px">
              <span>
                {{strings.debug_camping_values}}
              </span>
              <i style="font-size:38px;float: right;padding:10px;position:relative;top:0px;right:60px;">
                <label class="switch" style="position:absolute;">
                  <input type="checkbox" id="showValues_toggle" name="showValues_toggle" onchange="toggleDebugValues()">
                  <i class="slider round"></i>
                </label>
              </i>
            </div>
          </td>
        </tr>
        <tr @click="avatars.notSet=true;" style="cursor: pointer;">
          <td>
            <div style="max-height:55px">
              <span>
                {{strings.customize_ch_icons}}
              </span>
            </div>
          </td>
        </tr>
        <tr style="cursor: pointer;">
          <td v-on:click="modalGenerateURL()">
            <div style="max-height:55px">
              <span>
                {{strings.genera_url}}
              </span>
            </div>
          </td>
        </tr>
        <tr style="cursor: pointer;">
          <td v-on:click="menuLingua()">
            <div style="max-height:55px">
              <span>
                {{strings.language}}
              </span>
            </div>
          </td>
        </tr>
      </table>
    </div>

    <div id="my_teams_window" style="display:none;">
      <h2>{{strings.my_teams}}</h2><br>
      <table class="displaylistTable" style="margin-left:auto;margin-right:auto;">
        <tr v-for="key in displaySavedCamps">
          <td v-on:click="mostraRisultatoSalvato(key)">
            <div style="max-height:55px;">
              <span style="max-width:450px; overflow: hidden; display: inline-block; white-space: nowrap; text-overflow: ellipsis;">{{key}}</span>
            </div>
          </td>
        </tr>
      </table>
    </div>

    <div id="raid_map" style="display: none; margin: -8px;">
      <table class="maps_table">
        <tbody>
          <tr style="background-color: #f002;">
            <td>
              <span class="vert_table_title">{{strings.raid}}</span>
            </td>
            <td class="maps_column">
              <span>
                <img v-if="lingua==='cn'" src="../../img/Raid-Normal_zht.png" onclick="openImage(this.src)">
                <img v-else-if="lingua==='zht'" src="../../img/Raid-Normal_zht.png" onclick="openImage(this.src)">
                <img v-else src="../../img/Raid-Normal_en.png" onclick="openImage(this.src)">
                <span>
                  {{strings.normal}}
                </span>
              </span>
              <span>
                <img v-if="lingua==='cn'" src="../../img/Raid-Hell_zht.png" onclick="openImage(this.src)">
                <img v-else-if="lingua==='zht'" src="../../img/Raid-Hell_zht.png" onclick="openImage(this.src)">
                <img v-else src="../../img/Raid-Hell_en.png" onclick="openImage(this.src)">
                <span>
                  {{strings.hell}}
                </span>
              </span>
              <route-maker id="route_maker_window"></route-maker>
            </td>
          </tr>
          <tr style="background-color: #0fffff22">
            <td>
            </td>
            <td style="text-align: center;">
              {{strings.nixiedinfo}}<br><a href="https://game8.co/games/Epic-Seven/archives/284193 " target="_blank" style="text-decoration: none; color: red; text-shadow: 1px 1px 5px black;">https://game8.co/games/Epic-Seven/archives/284193</a><br>
            </td>
          </tr>
          <tr style="background-color: #0fffff22">
            <td>
              <span class="vert_table_title">{{strings.nixied}}</span>
            </td>
            <td class="maps_column">
              <span>
                <img src="https://img.game8.co/3235580/df915e10aa933192c93773c9ee67c6ed.png/original" onclick="openImage(this.src)">
                <span>
                  {{strings.nixied}} 1
                </span>
              </span>
              <span>
                <img src="https://img.game8.co/3238837/41e580783640902df84ad4154d45b02b.png/original" onclick="openImage(this.src)">
                <span>
                  {{strings.nixied}} 2
                </span>
              </span>
              <span>
                <img src="https://img.game8.co/3240084/c9d0e19e6d97cfc31f10c9c0f2381a73.png/original" onclick="openImage(this.src)">
                <span>
                  {{strings.nixied}} 3
                </span>
              </span>
              <span>
                <img src="https://img.game8.co/3258768/0dbd22118596b848cbe378e9eec42e13.jpeg/original" onclick="openImage(this.src)">
                <span>
                  {{strings.nixied}} 4
                </span>
              </span>
              <span>
                <img src="https://img.game8.co/3259720/8a3f4a32a2ae7ffce3cf23bf25d75511.jpeg/original" onclick="openImage(this.src)">
                <span>
                  {{strings.nixied}} 5
                </span>
              </span>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div id="saved_teams_stats" class="center" style="display: none;">
      <h2>{{strings.most_saved_teams}}
        <div style="float: right;">
          <button id="refreshStats" class="search_hero_filter" style="width: 70px" v-on:click="getSavedTeamsStats();">
            <i class="fa fa-refresh" aria-hidden="true" style="padding-right: 5px;"></i>{{strings.refresh_team_stats}}
          </button>
        </div>
      </h2>
      <br>
      <div style="width: 100%">
        <div id="team_tab_stats" class="tab_style activetab" style="margin-left: 0; margin-right: -2px" onclick="$('#char_tab_stats').removeClass('activetab'); $(this).addClass('activetab'); document.getElementById('teams_stats_tbody').style.display = 'block'; document.getElementById('char_stats_tbody').style.display = 'none'">
          {{strings.teams}}
        </div>
        <div id="char_tab_stats" class="tab_style" style="margin-left: -2px; margin-right: -1px;" onclick="$('#team_tab_stats').removeClass('activetab'); $(this).addClass('activetab');  document.getElementById('teams_stats_tbody').style.display = 'none'; document.getElementById('char_stats_tbody').style.display = 'block'">
          {{strings.heroes}}
        </div>
      </div>
    </div>

    <template  v-if="isSelectingCartesian">
      <hero_selector v-bind:selectable="cartesianSlotRoster()" v-bind:selected="cartesian_lock[isSelectingCartesian]" @right-click="rightClickHero" v-bind:slotnumber="isSelectingCartesian" @close-modal="addToCartesianLock"></hero_selector>
    </template>

    <div v-if="avatars.notSet==true" ref="popup-modal" class="modal" style="display: block;">
      <div class="modal-content modal-small modal-three-parts animate">
        <div>
          <span class="modal-title">
            {{strings.customize_ch_icons}}
          </span>
        </div>
        <div>
          <div style="min-height: 265px;">
            <div style="display: inline-block">
              <div style="display: inline-block; height: 180px; width: 90px;">
                <hero-icon :data="thisHeroData('alencia')" @clicked="avatars.scale=0.9" :img="getHeroAssets('alencia').icon" :removable="true" :hoverable="avatars.hoverable" :displayname="avatars.name" :name="thisHeroTranslatedName('alencia')" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="0.75" style="margin: auto; box-sizing: border-box; height: 114px;"></hero-icon>
                <span style="display: block;">
                  <input type="radio" id="scale0.9" value="0.9" v-model="avatars.scale">
                  <label for="scale0.9">
                    {{strings.small}}
                  </label>
                </span>
              </div>
              <div style="display: inline-block; height: 180px; width: 120px;">
                <hero-icon :data="thisHeroData('alencia')" @clicked="avatars.scale=1" :img="getHeroAssets('alencia').icon" :removable="true" :hoverable="avatars.hoverable" :displayname="avatars.name" :name="thisHeroTranslatedName('alencia')" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="1" style="margin: auto; box-sizing: border-box; height: 142px;"></hero-icon>
                <span style="display: block;">
                  <input type="radio" id="scale1" value="1" v-model="avatars.scale">
                  <label for="scale1">
                    {{strings.default}}
                  </label>
                </span>
              </div>
            </div>
            <div style="display: inline-block">
              <div style="display: inline-block; height: 180px; width: 140px;">
                <hero-icon :data="thisHeroData('alencia')" @clicked="avatars.scale=1.15" :img="getHeroAssets('alencia').icon" :removable="true" :hoverable="avatars.hoverable" :displayname="avatars.name" :name="thisHeroTranslatedName('alencia')" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="1.15" style="margin: auto; box-sizing: border-box; height:163px"></hero-icon>
                <span style="display: block;">
                  <input type="radio" id="scale1.15" value="1.15" v-model="avatars.scale">
                  <label for="scale1.15">
                    {{strings.medium}}
                  </label>
                </span>
              </div>
              <div style="display: inline-block; height: 180px; width: 150px;">
                <hero-icon :data="thisHeroData('alencia')" @clicked="avatars.scale=1.25" :img="getHeroAssets('alencia').icon" :removable="true" :hoverable="avatars.hoverable" :displayname="avatars.name" :name="thisHeroTranslatedName('alencia')" :showstars="avatars.stars" :role_attr="avatars.role_attr" :scale="1.25" style="margin: auto; box-sizing: border-box; height: 177px;"></hero-icon>
                <span style="display: block;">
                  <input type="radio" id="scale1.25" value="1.25" v-model="avatars.scale">
                  <label for="scale1.25">
                    {{strings.large}}
                  </label>
                </span>
              </div>
            </div>
          </div>
          <div>
            <div style="width:100%; min-width: 350px; margin: auto; text-align: start; font-size: 1.4em;">
              <span style="position: relative;width: 100%;display: inline-block;padding: 10px;">
                <label class="switch" style="width: 100%;" for="heroNameIconCheckbox">
                  <span style="height: 35px; line-height: 35px;">{{strings.name}}</span>
                  <input type="checkbox" id="heroNameIconCheckbox" v-model="avatars.name">
                  <i class="slider round"></i>
                </label>
              </span>
              <span style="position: relative;width: 100%;display: inline-block;padding: 10px;">
                <label class="switch" style="width: 100%;" for="role_attrIconsCheckbox">
                  <span style="height: 35px; line-height: 35px;">{{strings.attr_role}}</span>
                  <input type="checkbox" id="role_attrIconsCheckbox" v-model="avatars.role_attr">
                  <i class="slider round"></i>
                </label>
              </span>
              <span style="position: relative;width: 100%;display: inline-block;padding: 10px;">
                <label class="switch" style="width: 100%;" for="starsIconsCheckbox">
                  <span style="height: 35px; line-height: 35px;">{{strings.stars}}</span>
                  <input type="checkbox" id="starsIconsCheckbox" v-model="avatars.stars">
                  <i class="slider round"></i>
                </label>
              </span>
              <span style="position: relative;width: 100%;display: inline-block;padding: 10px;">
                <label class="switch" style="width: 100%;" for="hoverIconsCheckbox">
                  <span style="height: 35px; line-height: 35px; display: inline-block; max-width: 80%;">{{strings.enable_mouseover_zoom}}</span>
                  <input type="checkbox" id="hoverIconsCheckbox" v-model="avatars.hoverable">
                  <i class="slider round"></i>
                </label>
              </span>
            </div>
          </div>
        </div>
        <div>
          <span v-if="avatars.notSet" class="modal-text">
            {{strings.settings_samll_help}}
          </span>
          <button class="modal-button" @click="avatars.notSet=false; this.localStorage.setItem('avatars',JSON.stringify(avatars));">
            {{strings.save}}
          </button>
        </div>
      </div>
    </div>

    <!--<div v-if="last_version!=VERSION" ref="popup-modal-update" class="modal" style="display: block;">
      <div class="modal-content modal-small modal-three-parts">
        <div>
          <span class="modal-title">
            What's new!
          </span>
        </div>
        <div style="min-height: 170px;">
          <span style="text-align: start; display: inline-block;">
            T E X T   H E R E
            <a href="/old.html" style="text-align: center; text-decoration: none; color: var(--font-color);">If you are encountering issues with this version you can click here to use the old version.</a>
          </span>
        </div>
        <div>
          <div>
            <button class="modal-button" @click="last_version=VERSION; /*localStorage.setItem('last_version', JSON.stringify(last_version))*/">
              {{strings.confirm}}
            </button>
          </div>
        </div>
      </div>
    </div>-->

    <div id="toolbar" class="icon-bar"> <!-- nascondi toolbar durante il calcolo -->
      <!--<span id="icon-bar_user_window" onclick="/*setWindow('user_window')*/" style="background-image: url(../../favicons/android-chrome-192x192.png); background-size: cover; background-repeat: no-repeat;"></span>-->
      <span id="icon-bar_add_window" onclick="setWindow('add_window')"><!--&#43;--><i class="fa fa-plus" aria-hidden="true"></i></span>
      <span id="icon-bar_manage_window" onclick="setWindow('manage_window')"><!--&#9998;--><i class="fa fa-pencil-alt" aria-hidden="true"></i></span>
      <span id="icon-bar_advanced_window" onclick="setWindow('advanced_window')"><!--&#9876;--><i class="fa fa-book" aria-hidden="true"></i></span>
      <span id="icon-bar_calculate_window" onclick="app.calcolaRisultati; window.setWindow('calculate_window');" style="font-size:36px;">
        <!--Calcola-->
        <img src="./img/camp-fire.png" alt="calculate" style="margin-bottom: -10px; height: 40px;" />
      </span>
      <span id="icon-bar_settings_window" onclick="setWindow('extras_window')"><!--&#9881;--><i class="fa fa-cog"></i></span>
      <span id="icon-bar_my_teams_window" onclick="setWindow('my_teams_window')" style="display: none;"><i class="fa fa-save"></i></span>
      <span id="icon-bar_raid_map_window" onclick="setWindow('raid_map')" style="display: none;"><i class="fa fa-map"></i></span>
      <span id="icon-bar_team_stats_window" onclick="setWindow('saved_teams_stats');app.computedGetSavedTeamsStats;" style="display: none;"><i class="fa fa-chart-bar"></i></span>
      <span id="icon-bar_real_settings_window" onclick="setWindow('settings_window')" style="display: none;"><i class="fa fa-cog"></i></span>
    </div>

     <!-- Mostra durante il calcolo -->
    <div v-show="isLoadingResults" id="loading_camp_results">
      <div style="opacity: 0.3; filter: alpha(opacity=30); height:100%; width:100%; position:fixed; z-index:99; top: 0; right: 0;">
      </div> <!-- prevent user from changing menu -->
      <div class="center_img box_advanced_settings" style="height:200px;width:200px">
        <div class="center_img" style="text-align:center;"> 
          <img src="./img/calcul.gif" style="height:100px"/>
          <!--<i class="fa fa-cog fa-spin" style="font-size:30px"></i><br> -->
          {{strings.possibili_combinazioni}}<br><b>{{numeroCombinazioniPossibili}}</b>
        </div>
        <div style="display: none; width: 100%; height: 20px; background-color: transparent; padding: 0px; text-align: initial;border-radius: 0 0 15px 15px;position: absolute;bottom: 0;overflow: hidden;border: thin;border-style: solid none none;border-color: var(--search-border-color);">
          <span style="left: 40%; position:absolute"></span>
          <span id="calculationPer" style="height: 100%; width: 0%; background-color: var(--icon-bar-active); display: inline-block;"></span>
        </div>
      </div>
      <button style="z-index: 99;margin-right: 30px; width: auto; font-size: 16px; top: auto;bottom: 90px;right: 0;position: absolute;" class="search_hero_filter" onclick="restartCamperino();">{{strings.abort_calculation}}</button>
    </div>
    <div id="caricamentoIniziale" v-if="inizializzazione" class="center_img box_advanced_settings" style="z-index: 100; height: 100%; width: 100%; border-radius: 0; top: 49.9%;"> <!-- non è neccessario settare inizializzaione = true -->
      <div class="center_img" style="text-align:center;"> 
        <i class="fa fa-cog fa-spin" style="font-size:70px"></i>
        <div>
          Loading...
        </div>
      </div>
    </div>
    <div id="snackbar"></div> <!-- messaggio avvisi -->
  </div><!-- div id = app -->

  <script type="text/x-template" id="pagination">
    <ul class="pagination" v-if="totalPages>1">
      <li 
        class="pagination-item"
      >
        <button 
          type="button" 
          @click="onClickFirstPage"
          :disabled="isInFirstPage"
          aria-label="Go to first page"
        >
          &lt;&lt;
        </button>
      </li>
  
      <li
        class="pagination-item"
      >
        <button 
          type="button" 
          @click="onClickPreviousPage"
          :disabled="isInFirstPage"
          aria-label="Go to previous page"
        >
          &lt;
        </button>
      </li>
  
      <li v-for="page in pages" class="pagination-item">
        <button
          type="button" 
          @click="onClickPage(page.name)"
          :disabled="page.isDisabled"
          :class="{ activePage: isPageActive(page.name) }"
          :aria-label="`Go to page number ${page.name}`"
        >
          {{ page.name }}
        </button>
      </li>
  
      <li class="pagination-item">
        <button 
          type="button" 
          @click="onClickNextPage"
          :disabled="isInLastPage"
          aria-label="Go to next page"
        >
          &gt;
        </button>
      </li>
  
      <li class="pagination-item">
        <button 
          type="button" 
          @click="onClickLastPage"
          :disabled="isInLastPage"
          aria-label="Go to last page"
        >
          &gt;&gt;
        </button>
      </li>
    </ul>
  </script>

  <script type="text/x-template" id="hero_selector">
    <div class="modal" style="display: block;" @click="ranodomClick($event)">
      <form class="modal-content modal-big modal-three-parts animate" style="position: relative; z-index: 61; ">
        <span id="emptyDiv" v-if="filtering==true" @click="filtering=false;" style="z-index: 60; position: absolute; top: 0; left: 0; height: 100%; width: 100%;"></span>
        <div>
          <span class="modal-title">{{modalTitle}}</span>
          <button @click="filtering=true; removeSearchBar()" class="modal-button"><i class="fa fa-sliders" aria-hidden="true"></i>
            {{strings.filter}}
          </button>
          <div v-show="filtering" style="z-index: 62; position: absolute; min-height: 200px; min-width: 300px; background-color: black; top: 90%; border-radius: 10px; border: 1px solid rgb(119, 96, 72); right: 0px; display: flex; text-align: center; margin: 5px;">
            <div v-for="(i,key) in filters" style="flex: 1; margin: 5px;">
              <div v-for="j in i" v-bind:style="isActiveFilter(key,j)" style="position: relative; padding: 10px; font-size: 25px; box-sizing: border-box; height: 54px" @click="changeFilter( key, j)">
                <button v-if="j=='all'||j=='selected'" style="background-color: white; color: black; padding: 5px 20px; border-radius: 10px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;outline: none;border: none;font-size: 20px;">
                  {{strings[j]}}
                </button>
                <img v-else-if="key=='attribute'" v-bind:src="assetsAttribute(j)" />
                <img v-else-if="key=='role'" v-bind:src="assetsRole(j)" style="height: 34px;" />
                <span v-else-if="key=='rarity'" v-bind:class="'wrapper-hero-info rarity-' + j" style="display:block; height: 80%; margin-left: -10px;"></span>
              </div>
            </div>
          </div>
          <button class="modal-button fa fa-search" style="opacity: 0.5;" @click="this.snackbarMessage('Temporarily unavailable due to memory leak on Chrome!'); /*openSearchBar()*/">
            {{strings.search}}
          </button>
          <!--<div v-show="inputField" style="display: flex;position: absolute; z-index: 2;height: 50px;">
            <button @click="removeSearchBar()" style="flex: 0 1 10px;margin: 0; border-radius: 6px 0 0 6px;font-size: 17px;margin: 0;height: 100%;float: left;background-color: saddlebrown;" class="search_input">
              X
            </button>
            <input id="modal_selector_searchbar" :value="inputCharacter" ref="editInputField" v-bind:placeholder="strings.search+'...'" style="flex: 1;width: 100%;border-radius: 0;border: thin;border-style: solid none solid;box-sizing: border-box;height: 100%;" class="search_hero_filter searchBox" />
            <button class="fa fa-search search_input" style="flex: 0 1;height: 100%;margin: 0;">
            </button>
          </div>-->
        </div>
        <div>
          <hero-icon v-for="id in filteredData" v-bind:data="$root.thisHeroData(id)" @clicked="select(id)" @contextmenu="emitRightClick(id,$event)" :img="$root.getHeroAssets(id).icon" :displayname="$root.avatars.name" :name="$root.thisHeroTranslatedName(id)" :showstars="$root.avatars.stars" :role_attr="$root.avatars.role_attr" :scale="parseFloat($root.avatars.scale)" :hoverable="$root.avatars.hoverable" :selected="isSelected(id)"></hero-icon>
          <div v-if="heroes.length==0" style="display: flex; height: 100%;align-items: center;justify-content: center;">
            <div style="background-color:var(--bg-color); color:var(--font-color); border-radius: 30px; box-shadow:5px 5px 14px 1px var(--search-border-color);align-items: center;padding: 10px 50px;">
              <template v-if="filteredData.length==0">No heroes in your roster!</template>
              <template v-else>Sorry, your search returned no results...</template>
            </div>
          </div>
        </div>
        <div>
          <span class="modal-text">{{strings.selected}}: {{numberSelected}}</span>
          <button @click="closeModal()" class="modal-button">
            {{strings.confirm}}
          </button>
        </div>
      </form>
    </div>
  </script>

<script>
if (!Array.prototype.flat) {
    Object.defineProperty(Array.prototype, 'flat', {
      value: function(depth = 1) {
        return this.reduce(function (flat, toFlatten) {
          return flat.concat((Array.isArray(toFlatten) && (depth>1)) ? toFlatten.flat(depth-1) : toFlatten);
        }, []);
      }
    });
}
if (!Object.keys) { // can be improved
    Object.keys = function (obj) {
        var res = [];
        for (var key in obj) {
            res.push(key)
        }
        return res;
    }
}
if (!Object.values) {
    Object.values = function (obj) {
        return Object.keys(obj).map(function (e) {
            return obj[e];
        });
    };
}


    var userSettings = JSON.parse(localStorage.getItem('Settings') ? localStorage.getItem('Settings') : "{}");
    
    function defaultThemeColor() {
      try {
        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
          return 'dark';
        } else return 'light';
      } catch (err) {
          return 'light';
      };
    };
    function toggleCheck() {
      if (document.getElementById("darkModeCheck").checked === true) {
        document.documentElement.setAttribute('data-theme', 'dark');
        localStorage.setItem('theme', 'dark'); // salva preferenza per future visite
      }
      else {
        document.documentElement.setAttribute('data-theme', 'light');
        localStorage.setItem('theme', 'light'); // salva preferenza per future visite
      };    
    };
    const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;

    if (currentTheme) {
      document.documentElement.setAttribute('data-theme', currentTheme);

      if (currentTheme === 'dark') {
        var checkBoxes = $("input[name=darkModeCheck]");
        checkBoxes.attr('checked', true);
      };
    } else {
      if (defaultThemeColor() == 'dark') { // check OS settings and set dark theme if necessary
        document.documentElement.setAttribute('data-theme', 'dark');
        var checkBoxes = $("input[name=darkModeCheck]");
        checkBoxes.attr('checked', true);
      };
    };
    
    function setWindow(current) {
      scrollTo(0,0);
      //currentTab = current; // For swipe function
      document.getElementById('welcome').style.display='none';
      document.getElementById('add_window').style.display='none';
      document.getElementById('manage_window').style.display='none';
      document.getElementById('advanced_window').style.display='none';
      document.getElementById('calculate_window').style.display='none';
      document.getElementById('extras_window').style.display='none';

      document.getElementById('settings_window').style.display='none';
      document.getElementById('my_teams_window').style.display='none';
      document.getElementById('raid_map').style.display='none';
      document.getElementById('saved_teams_stats').style.display='none';
      //toolbar
      document.getElementById("icon-bar_add_window").className = "";
      document.getElementById("icon-bar_manage_window").className = "";
      document.getElementById("icon-bar_advanced_window").className = "";
      document.getElementById("icon-bar_calculate_window").className = "";
      document.getElementById("icon-bar_settings_window").className = "";

      document.getElementById("icon-bar_real_settings_window").className = "";
      document.getElementById("icon-bar_my_teams_window").className = "";
      document.getElementById("icon-bar_raid_map_window").className = "";
      document.getElementById("icon-bar_team_stats_window").className = "";

      switch (current) {
        case 'add_window':
          document.getElementById('add_window').style.display='block';
          document.getElementById("icon-bar_add_window").className = "active-icon-bar";
          break;
        case 'manage_window':
          document.getElementById('manage_window').style.display='block';
          document.getElementById("icon-bar_manage_window").className = "active-icon-bar";
          break;
        case 'advanced_window':
          document.getElementById('advanced_window').style.display='block';
          document.getElementById("icon-bar_advanced_window").className = "active-icon-bar";
          break;
        case 'calculate_window':
          document.getElementById('calculate_window').style.display='block';
          document.getElementById("icon-bar_calculate_window").className = "active-icon-bar";
          break;
        case 'extras_window':
          document.getElementById('extras_window').style.display='block';
          document.getElementById("icon-bar_settings_window").className = "active-icon-bar";
          break;
        case 'settings_window':
          document.getElementById('settings_window').style.display='block';
          document.getElementById("icon-bar_settings_window").className = "active-icon-bar";
          document.getElementById("icon-bar_real_settings_window").className = "active-icon-bar";
          break;
        case 'my_teams_window':
          document.getElementById('my_teams_window').style.display='block';
          document.getElementById("icon-bar_my_teams_window").className = "active-icon-bar";
          document.getElementById("icon-bar_settings_window").className = "active-icon-bar";
          break;
        case 'raid_map':
          document.getElementById('raid_map').style.display='block';
          document.getElementById("icon-bar_raid_map_window").className = "active-icon-bar";
          document.getElementById("icon-bar_settings_window").className = "active-icon-bar";
          break;
        case 'saved_teams_stats':
          document.getElementById('saved_teams_stats').style.display='block';
          document.getElementById("icon-bar_team_stats_window").className = "active-icon-bar";
          document.getElementById("icon-bar_settings_window").className = "active-icon-bar";
          break;
      };
    };

    function welcome_toggle(id,menu) {
      welcome_menu = document.getElementsByName("welcome_element");
      for (var i = 0; i<welcome_menu.length; i++) {
        $(welcome_menu[i]).removeClass('active_welcome');
      };
      $(menu).addClass('active_welcome');

      document.getElementById("welcome_message").style.display = "none";
      document.getElementById("whats_new_content").style.display = "none";
      document.getElementById("instructions_content").style.display = "none";
      document.getElementById("cool_websites_content").style.display = "none";
      document.getElementById("credits_content").style.display = "none";
      switch (id) {
        case 'welcome':
          document.getElementById("welcome_message").style.display = "block";
          break;
        case 'whats_new':
          document.getElementById("whats_new_content").style.display = "block";
          break;
        case 'instructions':
          document.getElementById("instructions_content").style.display = "block";
          break;
        case 'cool_websites':
          document.getElementById("cool_websites_content").style.display = "block";
          break;
        case 'credits':
          document.getElementById("credits_content").style.display = "block";
          break;
      };
    };


  var Notification = window.Notification || window.mozNotification || window.webkitNotification;
  // NOTIFICATION
  function checkNotificationPromise() {
    try {
      Notification.requestPermission().then();
    } catch(e) {
      return false;
    }

    return true;
  }
  var riceviNotifiche = userSettings.notification;

  if (riceviNotifiche === true) {
    var checkBoxes = $("#notifications_toggle");
    checkBoxes.attr('checked', true);
  };
  function switchNotifiche() {
    if ('permissions' in navigator) {
      if (riceviNotifiche == true) {
        riceviNotifiche = false;
        document.getElementById("notifications_toggle").checked = false;
      } else {
        riceviNotifiche = true;
        document.getElementById("notifications_toggle").checked = true;
      };
      app.writeSettings();
    };
  };

  function askNotificationPermission() {
    // Chiedi il permesso
    function handlePermission(permission) {
      // Conserva l'informazione
      if(!('permission' in Notification)) {
        Notification.permission = permission;
      }
      if (permission == "granted") {
        switchNotifiche();
      } else document.getElementById("notifications_toggle").checked = false;
    };

    // Controlla se il browser supporta notifiche
    if (!(Notification)) {
      console.log("This browser does not support notifications.");
    } else {
      if(checkNotificationPromise()) {
        Notification.requestPermission()
        .then((permission) => {
          handlePermission(permission);
        });
      } else {
        Notification.requestPermission(function(permission) {
          handlePermission(permission);
        });
      };
    };
  };

  function setToolbarPosition (f) {
    var f = f!=undefined ? f : "hor", appDoc = document.getElementById("app");
    if (f === "hor") {
      appDoc.style.marginLeft = "0";
      appDoc.style.marginBottom = "70px";
      document.getElementById("icon-bar_real_settings_window").style.display = "none";
      document.getElementById("icon-bar_my_teams_window").style.display = "none";
      document.getElementById("icon-bar_raid_map_window").style.display = "none";
      document.getElementById("icon-bar_team_stats_window").style.display = "none";
      document.getElementById("icon-bar_settings_window").style.display = "";
      document.getElementById("toolbar").className = "icon-bar";
    } else {
      appDoc.style.marginLeft = "90px";
      appDoc.style.marginBottom = "0";
      document.getElementById("icon-bar_settings_window").style.display = "none";
      document.getElementById("icon-bar_real_settings_window").style.display = "";
      document.getElementById("icon-bar_my_teams_window").style.display = "";
      document.getElementById("icon-bar_raid_map_window").style.display = "";
      document.getElementById("icon-bar_team_stats_window").style.display = "";
      document.getElementById("toolbar").className = "vertical-icon-bar";
    };
  };

  if (userSettings.verticalToolbar === undefined) {
    if (screen.width > 800 && screen.height >= 600) { // set vertical toolbar
      $("#toolbar_position").attr('checked', true);
      setToolbarPosition("ver");
    };
  } else {
    if (userSettings.verticalToolbar === true) {
      $("#toolbar_position").attr('checked', true);
      setToolbarPosition("ver"); 
    };
  };
  function toggleVerticalToolbar() {
    if (document.getElementById("toolbar_position").checked === true) setToolbarPosition("ver");
    else setToolbarPosition ();
    app.writeSettings();
  };

  if (userSettings.heroNameInGrid === true) $("#heroNameInGrid").attr('checked', true);
  function toggleNamesInGrid () {
    userSettings.heroNameInGrid = document.getElementById("heroNameInGrid").checked;
    app.showNamesInGrid = document.getElementById("heroNameInGrid").checked;
    app.writeSettings();
  };

  function openImage (link){
    $( "body" ).append(`
      <div id="imageViewer" style="z-index: 60; position: relative;">
        <div style="position: fixed; top: 0; left: 0; overflow-y: auto; scrollbar-width:initial; background-color: #0007; height: 100%; width: 100%;" onclick="$('#imageViewer').remove();$('body').removeClass('modal-open');">
          <img id="imageViewerObj" src="` + link + `" style="display: block; animation: animatezoom 0.4s; object-fit: scale-down;height: 100%;width: 100%;">
          <div style="width: 60px;height: 60px;position: fixed;right: 20px;top: 20px;background-color: #0006;border-radius: 40px;text-align: center;font-size: 48px;color: #fff8;cursor: pointer">x</div>
        </div>
        <div style="width: 60px;height: 60px;position: fixed;right: 20px;bottom: 20px;background-color: #0006;border-radius: 40px;text-align: center;font-size: 38px;color: #fff8;cursor: pointer" onclick="var img = document.getElementById('imageViewerObj'); if (img.style.objectFit === 'scale-down') {img.style.objectFit= ''; img.style.height='100%'; img.style.width='auto'; img.style.margin = 'auto'; this.children[0].className='fa fa-search-minus'} else {img.style.objectFit= 'scale-down'; img.style.height='100%'; img.style.width='100%'; this.children[0].className='fa fa-search-plus';};">
          <i class="fa fa-search-plus" aria-hidden="true" style="margin-top: 10px;"></i>
        </div>
      </div>
    `);
    $("body").addClass("modal-open");
  };


  //// context menu
  var showValues = false;
  if (showValues == true) {
    var checkBoxes = $("#showValues_toggle");
    checkBoxes.attr('checked', true);
  };
  function toggleDebugValues() {
    if (showValues == true) {
      showValues = false;
      document.getElementById("showValues_toggle").checked = false;
    } else {
      showValues = true;
      document.getElementById("showValues_toggle").checked = true;
    };
  };
  function getPosition(e) {
    var posx = 0;
    var posy = 0;

    if (!e) var e = window.event;

    if (e.pageX || e.pageY) {
      posx = e.pageX;
      posy = e.pageY;
    } else if (e.clientX || e.clientY) {
      posx = e.clientX + document.body.scrollLeft + 
                        document.documentElement.scrollLeft;
      posy = e.clientY + document.body.scrollTop + 
                        document.documentElement.scrollTop;
    }

    return {
      x: posx,
      y: posy
    };
  };

  var tastoDestro = 0;
  if (document.addEventListener) {
    document.addEventListener('click', function(e) {
      if ($(e.target).parents("#debugHeroInfo").length>0 ) return;
      if (tastoDestro != 0) {
        tastoDestro = 0;
        $('#debugHeroInfo').remove();
      }; 
    }); 
    document.addEventListener('contextmenu', function(e) {
      if (document.getElementById("debugHeroInfo") != null)
        if (tastoDestro != 0) {
          tastoDestro = 0;
          $('#debugHeroInfo').remove();
        }; 
    }, false);
  } else {
    document.attachEvent('oncontextmenu', function() {
      window.event.returnValue = false;
    });
  };
  function debugRightMenu(e,hero){
    tastoDestro = 1;
    var posX, posY;
    let clickCoords = getPosition(e);
    let clickCoordsX = clickCoords.x;
    let clickCoordsY = clickCoords.y;

    let menuWidth = 200 + 4;
    let menuHeight = 480 + 4;
    let currentYPosition = e.pageY;
    
    let windowWidth = window.innerWidth;
    let windowHeight = window.innerHeight;

    if ( (windowWidth - clickCoordsX - 50) < menuWidth ) {
      posX = clickCoordsX - menuWidth - 15 + "px";
    } else {
      posX = clickCoordsX + "px";
    }

    if ( (windowHeight - e.clientY - 50) < menuHeight ) {
      posY = clickCoordsY + windowHeight - e.clientY - menuHeight - 50 + "px";
    } else {
      posY = clickCoordsY + "px";
    }

    var topics = "";
    for (var key in app.HeroDB[hero].camping.values) {
      topics += `<div style="border-bottom: 1px solid grey;">` + app.translateTopics(key) + " " + '<span style="float: right;">' + app.HeroDB[hero].camping.values[key] + '</span></div>'
    };
    $( "#app" ).append(`
    <div id="debugHeroInfo" class="blur" style="z-index: 1; width:200px;position:absolute; top:` + posY + `; left:` + posX + `; padding: 10px;">
      ` + "<center>" + app.thisHeroTranslatedName(hero) + "</center>" +
      `<div style="font-size:12px">` +
        app.strings.topics + ": " + app.translateTopics(app.HeroDB[hero].camping.topics[0]) + ", " +  app.translateTopics(app.HeroDB[hero].camping.topics[1]) + "<br><br>" +
        topics
      + `</div>
      </div>
    `);
    e.preventDefault(); // hide left click
  };

  function mandaNotificaCompletamento(){
    if (riceviNotifiche == true) {
      if (document.visibilityState != 'visible') {
        var icon = "../../favicons/android-chrome-192x192.png" // "https://cdn.glitch.com/5c21c869-ea9a-48ba-b019-90cd493f45cd%2Fcamp-fire-icon%20small.png?v=1585067234171"
        var notification = new Notification(app.strings.notification_title, { body: app.strings.notification_ready, icon: icon }); // manda notifica di completamento
      };
    };
  };

  function snackbarMessage(text) {
    //$( "#snackbar" ).text(text);
    var x = document.getElementById("snackbar");
    x.innerHTML = text;
    x.className = "show";
    setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
  };

  function sendTeamUsageStatistics(data) {
    $.ajax({
        url: "https://ceciliabotgithub.glitch.me/team_statistics",
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify( data ),
        success: function (response) {
        },
        error: function(jqXHR, textStatus, errorThrown) {
          console.log("could not upload team data");
        }
    });
  };

  function generateUrl(roster) {
    var baseURL = window.location.origin;
    var encodeRoster = btoa(JSON.stringify(Object.keys(roster)));
    return baseURL + window.location.pathname + "?camproster=" + encodeRoster;
  };
  function copyText(id){
    var elm = document.getElementById(id);
    if(document.body.createTextRange) {// for Internet Explorer
      var range = document.body.createTextRange();
      range.moveToElementText(elm);
      range.select();
      document.execCommand("Copy");
    }
    else if(window.getSelection) {// other browsers
      var selection = window.getSelection();
      var range = document.createRange();
      range.selectNodeContents(elm);
      selection.removeAllRanges();
      selection.addRange(range);
      document.execCommand("Copy");
    };
    snackbarMessage("Copied to clipboard");
  };

  ///Component
  const pagination = {
    name: 'pagination',
    template: '#pagination',
    props: {
      maxVisibleButtons: {
        type: Number,
        required: false,
        default: 4
      },
      totalPages: {
        type: Number,
        required: true
      },
      total: {
        type: Number,
        required: true
      },
      perPage: {
        type: Number,
        required: true
      },
      currentPage: {
        type: Number,
        required: true
      },
    },
    computed: {
      pages() {
        const range = [];
        var remainingLeft = 0;
        var remainingRight = 0;
        var endPage = this.currentPage + Math.floor(this.maxVisibleButtons/2);
        var startPage = this.currentPage - Math.ceil(this.maxVisibleButtons/2);
        if ( endPage>this.totalPages ) remainingRight = endPage-this.totalPages, endPage = this.totalPages;
        if (startPage<1) remainingLeft = Math.abs( 1-startPage ), startPage = 1;
        endPage += remainingLeft;
        startPage -= remainingRight;
        if ( endPage>this.totalPages ) endPage = this.totalPages;
        if (startPage<1) startPage = 1;

        for (let i = startPage; i <= endPage; i+= 1 ) {
          if (i>0) {
            range.push({
              name: i,
              isDisabled: i === this.currentPage 
            });
          };
        };

        return range;
      },
      isInFirstPage() {
        return this.currentPage === 1;
      },
      isInLastPage() {
        return this.currentPage === this.totalPages;
      },
    },
    methods: {
      onClickFirstPage() {
        this.$emit('pagechanged', 1);
      },
      onClickPreviousPage() {
        this.$emit('pagechanged', this.currentPage - 1);
      },
      onClickPage(page) {
        this.$emit('pagechanged', page);
      },
      onClickNextPage() {
        this.$emit('pagechanged', this.currentPage + 1);
      },
      onClickLastPage() {
        this.$emit('pagechanged', this.totalPages);    
      },
      isPageActive(page) {
        return this.currentPage === page;
      },
    }
  };
  const hero_icon = {
    functional: true,
    name: 'hero_icon',
    props: {
      data: {
        type: Object,
        required: true,
        default: function () {
          return {};
        }
      },
      img: {
        type: String,
        required: false,
        default: "https://cdn.glitch.com/6c14ca82-3bcb-4fd6-afa7-815b95e04a14%2Fc0000_s.png"
      },
      name: {
        type: String,
        required: false,
        default: "<NAME>"
      },
      removable: {
        type: Boolean,
        required: false,
        default: false
      },
      selected: {
        type: Boolean,
        required: false,
        default: false
      },
      displayname: {
        type: Boolean,
        required: false,
        default: false
      },
      role_attr: {
        type: Boolean,
        required: false,
        default: true
      },
      showstars: {
        type: Boolean,
        required: false,
        default: false
      },
      hoverable: {
        type: Boolean,
        required: false,
        default: true
      },
      size: {
        type: Number,
        required: false,
        default: 75
      },
      scale: {
        type: Number,
        required: false,
        default: 1
      }
    },
    render: function (h,ctx) {
      let roleIcon = {knight: "knight",warrior:"warrior",assassin: "thief",mage: "mage", ranger: "ranger", manauser: "soul-weaver"},
          attrIcon = {fire: "fire", wind: "earth", ice: "ice", light: "light", dark: "mdark"};
      if (!ctx.props.data._id) return;
      return h('div', {key: ctx.props.data._id, attrs: ctx.data.attrs, on: {click: event => event.target.className.indexOf('removeHero') !=-1 ? ctx.listeners['remove'](ctx.props.data._id) : ctx.listeners['clicked'] ? ctx.listeners['clicked'](ctx.props.data._id) : null, contextmenu: event => ctx.listeners['contextmenu'](event,ctx.props.data._id)}, class: [{'heroImgList': true, 'noselect': true, hoverIcon: ctx.props.hoverable},ctx.data.staticClass], style: [{padding: 12*ctx.props.scale + 'px'},ctx.data.staticStyle], directives: ctx.data.directives},[
          h('div', {style: {position: "relative", display: "inline-block", verticalAlign: "top", height: ctx.props.size*ctx.props.scale+"px", width: ctx.props.size*ctx.props.scale+"px"}}, 
            [/* icon wrapper*/
              h('img', {class: "heroAvatar", attrs: {src: ctx.props.img, onerror: 'this.src=app.getHeroAssets(\''+ctx.props.data._id+'\', \'onerror\').icon;this.onerror=null;', alt: ctx.props.name}}),
              ctx.props.role_attr? h('div', {class: "attribute-role", style: {backgroundImage: "url(https://assets.epicsevendb.com/class/cm_icon_role_"+ roleIcon[ctx.props.data.role] +".png),url(https://assets.epicsevendb.com/attribute/cm_icon_pro"+ attrIcon[ctx.props.data.attribute] +".png)"}}) : null,
              ctx.props.showstars? h('div', {class: "wrapper-hero-info rarity-"+ctx.props.data.rarity}) : null,
              ctx.props.selected? h('div', {class: "top-right animate-flicker", style: {fontSize: ctx.props.scale*24+"px"}},'🔒') : null
            ]
          ),
          ctx.props.removable ? h('span', {class: "removeHero", style: {fontSize: 20*ctx.props.scale+"px"}, attrs: {title: "Remove " + ctx.props.name}}, '×') : null,
          ctx.props.displayname ? h('p',{class: "heroNameLabel", style: {width: (ctx.props.size*ctx.props.scale + (ctx.props.removable ? 20*ctx.props.scale : 0) ) + "px", fontSize: 14*ctx.props.scale+"px", height: 50*ctx.props.scale+"px"}}, ctx.props.name) : null
        ]
      )
    }
  };
  const hero_selector = {
    name: 'hero_selector',
    template: '#hero_selector',
    components: {
      "hero-icon": hero_icon
    },
    props: {
      selectable: {
        type: Array,
        required: true,
        default: []
      },
      selected: {
        type: Array,
        required: false,
        default: []
      },
      title: {
        type: String,
        required: false,
        default: undefined
      },
      slotnumber: {
        type: String,
        required: false,
        default: "0"
      },
      forceSelection: {
        type: Boolean,
        required: false,
        default: false
      },
      maxSelectable: {
        type: Number,
        required: false,
        default: -1
      }
    },
    data: function () {
      return {
        inputField: false,
        inputCharacter: "",
        filtering: false,
        filters: {attribute: ["all","fire","ice","wind","light","dark"], role: ["all", "warrior", "knight", "assassin", "ranger", "mage", "manauser"], rarity: ["all", 5, 4, 3, "selected"]},
        filter: {},
        filteredData: this.selectable
      }
    },
    computed: {
      heroes: function() {
        let tmp = {};
        for (var i in this.selectable) {
          tmp[this.selectable[i]] = this.$root.HeroDB[this.selectable[i]];
        };
        return tmp;
      },
      modalTitle: function () {
        if (!this.title) return this.strings.multilock_slot + " " + (parseInt(this.slotnumber) + 1);
        return title;
      },
      strings: function () {
        try {
          return this.$root.strings;
        } catch (err) { /* for safety */
          console.log(err);
          return {};
        };
      },
      numberSelected: function () {
        return this.selected.length;
      }
    },
    methods: {
      hero: function (id) {
        return this.heroes[id];
      },
      isSelected: function (hero) {
        return this.selected.includes(hero);
      },
      assetsRole: function(role) {
        switch (role) {
          case "manauser": 
            return "https://assets.epicsevendb.com/class/cm_icon_role_soul-weaver.png"
            break;
          case "assassin": 
            return "https://assets.epicsevendb.com/class/cm_icon_role_thief.png"
            break;
          case "warrior": 
            return "https://assets.epicsevendb.com/class/cm_icon_role_warrior.png"
            break;
          case "mage": 
            return "https://assets.epicsevendb.com/class/cm_icon_role_mage.png"
            break;
          case "ranger": 
            return "https://assets.epicsevendb.com/class/cm_icon_role_ranger.png"
            break;
          default:
            return "https://assets.epicsevendb.com/class/cm_icon_role_knight.png"
        }
      },
      assetsAttribute: function(attr) {
        switch (attr) {
          case "fire": 
            return "https://assets.epicsevendb.com/attribute/cm_icon_profire.png"
            break;
          case "ice": 
            return "https://assets.epicsevendb.com/attribute/cm_icon_proice.png"
            break;
          case "wind": 
            return "https://assets.epicsevendb.com/attribute/cm_icon_proearth.png"
            break;
          case "light": 
            return "https://assets.epicsevendb.com/attribute/cm_icon_prolight.png"
            break;
          case "dark": 
            return "https://assets.epicsevendb.com/attribute/cm_icon_promdark.png"
            break;
          default:
            return "https://assets.epicsevendb.com/attribute/cm_icon_profire.png"
        }
      },
      select: function(e) {
        if (this.selected.includes(e)) {
          this.selected.splice(this.selected.indexOf(e), 1)
        } else {
          this.selected.push(e);
        }
      },
      localizedName: function (id) {
        if (this.translatedNames[id]) return this.translatedNames[id];
        else return "";
      },
      isActiveFilter: function (type, filter) {
        let slectedStyle = {"backgroundColor": "var(--icon-bar-active)", borderRadius: "10px"};
        if (this.filter[type]) {
          if (this.filter[type] == filter) return slectedStyle;
        };
        if (!this.filter[type] && filter == "all") return slectedStyle;
        return {"backgroundColor": "transparent"}; // no background-color
      },
      heroesFilter: function() {
        var tmp = JSON.parse(JSON.stringify(this.heroes)); // make a copy
        let text = this.inputCharacter.toLowerCase();
        for (var hero in tmp){
          if (text && tmp[hero].name.toLowerCase().indexOf(text) == -1 && this.name.toLowerCase().indexOf(text) == -1) {delete tmp[hero];continue};
          for (var i in this.filter) {
            if (!tmp[hero]) break;
            if (isNaN(this.filter[i]) && this.filter[i].toLowerCase() == "all") continue;
            if (isNaN(this.filter[i]) && this.filter[i] == "selected" && this.isSelected(hero)) continue;
            if (tmp[hero][i] != this.filter[i]) delete tmp[hero];
          };
        };
        this.filteredData = Object.keys(tmp);
      },
      changeFilter: function(type,value) {
        this.filter[type] = value;
        this.heroesFilter();
      },
      openSearchBar: function() {
        this.inputField=true; 
        this.filtering=false;
        this.$nextTick(() => {
          this.$refs.editInputField.focus();
        });
      },
      removeSearchBar: function () {
        this.inputCharacter = "";
        this.inputField = false;
      },
      ranodomClick: function (e) {
        e.preventDefault();
        if (e.target.className=="modal") return this.closeModal();
        //else console.log(e);
      },
      emitRightClick(e,event) {
        this.$emit('right-click', e,event);
      },
      closeModal() {
        if (this.forceSelection && this.selected.length==0) return; // must select something
        this.$emit('close-modal', this.selected);
        this.$destroy(true);
      }
    },
    watch: {
      inputCharacter: function () {
        this.filter = {}; //remove filters when searching by name
        this.heroesFilter();
      },
    },
    mounted: function() {
    },
    beforeDestroy: function() {
    }
  };

  var CampData = {"personalities":["Introvert","Hot and Cold","Cherub","Narcissist","Arrogant","Debate Addict","Academic","Heroism","Traumatized","Loyal","Realistic","Selfish","Individualistic","Altruistic","Glutton","Alcoholic","Lovesick","Lustful","Psychopath","Religious","Optimistic","Pessimistic","Indifferent","Natural","Obsessive","Hard Worker","Extrovert","Envious","Cool-Headed","Free","Escapist"],"topics":[{"name":"Criticism","values":[-1,-2,-2,3,5,5,2,-5,3,-1,3,3,2,-3,null,2,null,null,3,-3,-2,3,0,-2,0,2,0,3,2,1,2]},{"name":"Reality Check","values":[-3,0,-2,3,-3,3,2,-3,-3,1,3,0,2,-3,null,-2,null,null,2,0,-2,3,0,-2,-3,1,0,0,2,-1,-3]},{"name":"Heroic Tale","values":[1,0,2,3,5,-3,0,3,1,3,-1,0,0,-3,null,3,null,null,-3,0,3,-2,1,2,0,2,3,2,0,0,-1]},{"name":"Comforting Cheer","values":[3,3,2,5,3,0,1,3,-3,3,0,0,2,3,null,3,null,null,3,3,0,5,0,2,-1,5,3,-2,-2,1,3]},{"name":"Cute Cheer","values":[3,3,2,5,4,0,1,1,1,1,1,1,1,3,null,2,null,null,0,0,3,-3,1,2,1,2,3,2,0,2,2]},{"name":"Heroic Cheer","values":[3,0,2,3,-3,1,1,3,0,5,2,0,2,2,null,3,null,null,-3,2,3,-1,0,2,1,2,3,3,0,1,-3]},{"name":"Sad Memory","values":[0,3,2,0,0,-3,0,3,3,3,0,0,1,5,null,1,null,null,4,4,1,-2,0,2,-3,3,-2,-1,0,1,3]},{"name":"Joyful Memory","values":[2,2,2,0,0,0,0,3,3,2,0,2,3,3,null,2,null,null,0,2,4,1,1,2,0,3,3,1,1,1,3]},{"name":"Happy Memories","values":[2,2,2,0,2,0,0,3,0,2,0,0,2,3,null,1,null,null,-2,2,2,1,0,2,-1,-3,2,1,0,1,2]},{"name":"Unique Comment","values":[0,1,0,2,0,-1,-3,2,3,0,0,0,0,0,null,1,null,null,5,2,3,-1,1,0,3,0,0,1,3,2,1]},{"name":"Self-Indulgent","values":[-3,-3,2,0,-3,1,5,-1,1,-2,-1,-2,0,-2,null,2,null,null,1,0,1,-2,0,2,-1,-3,2,2,0,1,-2]},{"name":"Occult","values":[0,0,-1,-3,3,-3,3,0,3,-2,-1,0,0,-1,null,-2,null,null,3,-3,1,4,0,-1,1,0,1,2,0,1,2]},{"name":"Myth","values":[1,0,2,2,5,3,5,3,0,1,-1,0,0,1,null,0,null,null,-3,3,1,-3,0,2,0,0,1,4,0,1,-3]},{"name":"Bizarre Story","values":[2,0,-1,-3,-3,-3,0,-2,-2,-1,-2,0,-2,-1,null,-2,null,null,5,-2,1,3,0,-1,5,0,2,0,0,2,-2]},{"name":"Food Story","values":[0,0,4,0,3,0,0,2,0,2,0,0,1,0,null,3,null,null,-3,1,3,-2,4,4,0,3,1,2,0,1,2]},{"name":"Horror Story","values":[-1,-2,-5,-3,-2,0,-5,2,0,0,2,3,0,-2,null,-3,null,null,5,0,1,-2,-2,-5,3,-1,3,0,0,1,-2]},{"name":"Gossip","values":[3,1,1,1,-1,3,2,-2,-3,-3,1,3,-2,1,null,0,null,null,-3,-1,1,-3,0,1,0,-3,2,0,0,1,1]},{"name":"Dream","values":[1,2,2,2,0,2,0,2,2,1,-3,0,2,3,null,2,null,null,2,2,2,0,0,2,2,3,2,3,0,4,0]},{"name":"Advice","values":[3,1,1,2,3,3,1,2,-2,2,2,0,2,5,null,3,null,null,3,2,0,0,0,1,2,2,2,-2,0,1,2]},{"name":"Complain","values":[-3,-1,1,-2,-2,2,1,-3,-3,-1,0,3,2,1,null,2,null,null,-5,2,1,-2,0,1,-5,-5,0,-2,0,1,2]},{"name":"Belief","values":[3,0,0,4,-3,-1,0,-1,5,-3,2,3,1,-3,0,3,0,0,3,3,2,-3,0,1,3,1,1,3,0,-1,-3]},{"name":"Interesting Story","values":[2,1,1,1,-1,1,2,1,1,0,-1,0,1,1,null,3,null,null,1,0,2,1,1,1,0,1,2,1,1,5,3]}]}
  function CampDataBuilder(personalities = []) {
    var res = {},
        p = Array.isArray(personalities) ? personalities : [-1, -1];
    
    for (var i = 0; i < CampData.topics.length; i++) {
        var topic = CampData.topics[i];
        res[topic.name] = Math.max(topic.values[p[0]] || 0, 0) + Math.max(topic.values[p[1]] || 0, 0);
    }
    return res;
  }


    var app = new Vue({
        el: '#app',
        components: {
          pagination: pagination,
          "hero-icon": hero_icon,
          hero_selector: hero_selector
        },
        data: function () {
            return {
              VERSION: 1.0,
              last_version: localStorage.getItem('last_version'), /* if different from VERSION a popup will appear*/
              avatars: JSON.parse(localStorage.getItem('avatars') || '{"name": false, "role_attr": true, "stars": false, "scale": 1, "hoverable": true, "notSet": false}'),
              strings: {},

              /* Database (add hero window) */
              HeroDB: {},
              databaseSort: "name",
              displayList: [],

              buffList: {
                "stic_debuf_impossible": {"name": "Immunity", "id": 12},
                "stic_att_up": {"name": "Attack up", "id": 1},
                "stic_att_up2": {"name": "Attack up (Greater)", "id": 44},
                "stic_def_up": {"name": "Defense up", "id": 2},
                "stic_speed_up": {"name": "Speed up", "id": 3},
                "stic_dodge_up": {"name": "Evasion", "id": 10},
                "stic_protect": {"name": "Barrier", "id": 5},
                "stic_cri_up": {"name": "Crit chance up", "id": 4},
                "stic_cridmg_up": {"name": "Crit damage up", "id": 9},
                "stic_crires_up": {"name": "Crit Resistance", "id": 40},
                "stic_invincible": {"name": "Invincibility", "id": 6},
                "stic_endure": {"name": "Skill nullifier", "id": 46},
                "stic_heal": {"name": "Continuous Healing", "id": 11},
                "stic_hide": {"name": "Stealth", "id": 15},
                "stic_immortality": {"name": "Immortality", "id": 14},
                "stic_reflect": {"name": "Reflect", "id": 13},
                "stic_counter": {"name": "Counter", "id": 7}
              },
              debuffList: {
                "stic_def_dn": {"name": "Def down", "id": 18},
                "stic_speed_dn": {"name": "Speed down", "id": 19},
                "stic_att_dn": {"name": "Attack down", "id": 17},
                "stic_blind": {"name": "Blind", "id": 22},
                "stic_target": {"name": "Target", "id": 26},
                "stic_buf_impossible": {"name": "Unbuffable", "id": 29},
                "stic_heal_impossible": {"name": "Unhealable", "id": 27},
                "stic_stun": {"name": "Stun", "id": 20},
                "stic_provoke": {"name": "Provoke", "id": 25},
                "stic_silence": {"name": "Silence", "id": 28},
                "stic_sleep": {"name": "Sleep", "id": 21},
                "stic_blood": {"name": "Bleed", "id": 32},
                "stic_dot": {"name": "Poison", "id": 24},
                "stic_blaze": {"name": "Burn", "id": 31},
                "stic_vampire": {"name": "Vampire", "id": 23},
                "stic_bomb": {"name": "Bomb", "id": 53}
              },

              /* User's roster */
              myHeroesList: {},
              displayMyHeroes: [],
              rosterLength: 0, /* Used to make roster object reactive*/
              rosterSort: 'date',

              locked: [],
              classe: {knight: 0, warrior: 0, assassin: 0, manauser: 0, ranger: 0, mage: 0},
              elemento: {fire: 0, ice: 0, wind: 0, dark: 0, light: 0},
              debuffs: [],
              buffs: [],
              AoE: false,
              noS1debuffs: false,
              noDebuffs:  false,
              mustIncludeDispel: false,
              mustIncludeCleanser: false,
              cartesian_lock: [[],[],[],[]],
              isSelectingCartesian: false,
              risultati: [],
              currentResultsPage: 1,
              topSavedCamps: [],
              topSavedCampsPage: 1,
              savedCamps: JSON.parse(localStorage.getItem('savedCamps') ? localStorage.getItem('savedCamps') : "{}"),
              displaySavedCamps: Object.keys(JSON.parse(localStorage.getItem('savedCamps') ? localStorage.getItem('savedCamps') : "{}")),
              customizedResuts: {numeroMassimo: true, n: 200, minMorale: false, morale: 0, noImmagini: false, advMuteLocked: false},
	            displayStyle: "grid",
	            isLoadingResults: false,
              inizializzazione: true, //nascondi tutto durante il caricamento iniziale di vue
              numeroCombinazioniPossibili: "/",
              lingua: "en", // Just a placeholder during boot, language is set at line 1701 and 1705
              lockType: 1,
              translatedName: {}
            };
        },
        methods: {
          changeResultsPage: function (page) {
            scrollTo(0,0)
            this.currentResultsPage = page;
          },
          heroId: function (hero) {
            return this.HeroDB[hero].id;
          },
          thisHeroData: function(hero) {
            return this.HeroDB[hero]
          },
          thisHeroTranslatedName: function(heroid) {
            if (!heroid) return; 
            if (this.translatedName[heroid]) {
              return this.translatedName[heroid]
            } else {
              if (!this.thisHeroData(heroid)) return heroid;
              return this.thisHeroData(heroid).name;
            }
          },
          getHeroAssets: function (_id, f) {
            if (this.HeroDB[_id]){
              if (!this.HeroDB[_id].assets) this.HeroDB[_id].assets = {icon: 'https://assets.epicsevendb.com/_source/face/' + this.thisHeroData(_id).id + '_s.png'};
              if (f === "onerror") this.HeroDB[_id].assets = {icon: 'https://res.cloudinary.com/ceciliabot/image/upload/epic-seven/face/' + this.thisHeroData(_id).id + '_s.png'};
              return this.HeroDB[_id].assets;
            } else return {icon: ""};
          },
          capitalize: function(string) {
              return string[0].toUpperCase() + string.slice(1).replace(/-/gi," "); 
          },
          updateUserData: function() { // aggiorna i dati sul server
            localStorage.setItem('Heroes', JSON.stringify(this.myHeroesList) );
          },
          addHero: function (hero) {
            if (!this.myHeroesList[hero]) {
              //this.myHeroesList.push(hero);
              this.myHeroesList[hero] = this.HeroDB[hero]; // aggiunge l'object del nuovo eroe
              this.rosterLength +=1; // usa per indicare a vue che qualcosa è cambiato
              this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}); // <=="Add Heroes" screen / aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
              this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}, "MyHeroes"); // <== "Manage Heroes" screen / aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
              this.updateUserData();
            }
          },
          addShownHeroes: function () {
            for (var i = 0; i < this.displayList.length; i++) {
              this.myHeroesList[this.displayList[i]] = this.HeroDB[this.displayList[i]];
            };
            this.rosterLength = Object.keys(this.myHeroesList).length; // Update roster length
            this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}); // aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
            this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}, "MyHeroes"); // aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
            this.updateUserData();
          },
          removeHero: function (hero) {
            //this.myHeroesList.splice(this.myHeroesList.indexOf(hero), 1);
            delete this.myHeroesList[hero];
            this.rosterLength -=1; // usa per indicare a vue che qualcosa è cambiato
            if (this.locked.includes(hero)) { // lock
               this.locked.splice(this.locked.indexOf(hero), 1)
            };
            for (var i = 0; i < this.cartesian_lock.length; i++) {
              this.removeCartesian_lock(i, hero);
            };
            this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}); // aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
            this.displayMyHeroes.splice(this.displayMyHeroes.indexOf(hero), 1); // rimuovi dalla display list dei miei eroi se presente (sempre presente)
            this.updateUserData();
          },
          removeShownHeroes: function () {
            for (var i = 0; i < this.displayMyHeroes.length; i++) {
              delete this.myHeroesList[this.displayMyHeroes[i]];
              if (this.locked.includes(this.displayMyHeroes[i])) { // lock
                this.locked.splice(this.locked.indexOf(this.displayMyHeroes[i]), 1)
              };
            };
            this.rosterLength = Object.keys(this.myHeroesList).length; // Update roster length
            this.displayMyHeroes = [];
            this.filtroTuttiGliEroi({className: "search_hero_filter", name: "", value: ""}); // aggiorna i filtri per evitare bug se l'opzione nascondi eroi già in team è attiva
            this.updateUserData();
          },
          isInTeam: function(hero) {
            if (this.myHeroesList[hero])
              return true
            else 
              return false;
          },
          isLocked: function(hero) {
            if (this.locked.includes(hero))
              return true;
            else
              return false;
          },
          lockHero: function(hero) {
            if (!this.locked.includes(hero)) { // lock
              if (this.locked.length < 4) {
                this.locked.push(hero);
              } else {
                snackbarMessage(this.strings.cant_lock_more_heroes)
              }
            } else { // già locked -> sblocca
              this.locked.splice(this.locked.indexOf(hero), 1)
            };
          },
          writeSettings: function() {
            var settings = JSON.stringify({notification: riceviNotifiche, lingua: this.lingua, verticalToolbar: document.getElementById("toolbar_position").checked});
            localStorage.setItem('Settings', settings);
            userSettings = JSON.parse(settings);
          },
          alertUserAction: function (f) {
            let action, message;
            if (f === "addDisplayed") {
              if (this.displayList.length==0) return;
              message = this.strings.confirm_add_heroes.replace(/<N>/g, this.displayList.length);
            } else if (f === "removeDisplayed") {
              if (this.displayMyHeroes.length==0) return;
              message = this.strings.confirm_remove_heroes.replace(/<N>/g, this.displayMyHeroes.length);
            };
            var answer = window.confirm(message);
            if (answer) { // answer = true
              if (f === "addDisplayed") {
                this.addShownHeroes();
              } else if (f === "removeDisplayed") {
                this.removeShownHeroes();
              };
            }
            else { // cancel
            }
          },
          rightClickHero: function (key,e) { 
            e.preventDefault();
            setTimeout(() => {
              if (tastoDestro === 1) $("#debugHeroInfo").remove(), tastoDestro = 0;
              if (showValues) return debugRightMenu(e, key);
              var hero = this.thisHeroData(key);
              var self = this;
              /* E7DB language tags */
              var _lingua = "/"
              if (this.lingua === "kr") _lingua = "/ko/"
              else if (this.lingua === "jp") _lingua = "/jp/"
              else if (this.lingua === "cn") _lingua = "/cn/"
              else if (this.lingua === "zht") _lingua = "/tw/"
              else if (this.lingua === "fr") _lingua = "/fr/"
              else if (this.lingua === "pt") _lingua = "/pt/"
              else if (this.lingua === "es") _lingua = "/es/"
              else if (this.lingua === "th") _lingua = "/th/"
              else if (this.lingua === "de") _lingua = "/de/"
              var e7dbLink = "https://epicsevendb.com" + _lingua + "hero/"+ hero._id;

              tastoDestro = 1;

              let menuWidth = 400;
              let menuHeight = 480;
              let _app = document.getElementById("app");
              //let margin_bottom = parseInt( (_app.currentStyle?.marginTop || document.defaultView?.getComputedStyle(_app, '')?.getPropertyValue('margin-bottom') || 0 ), 10);
              let margin_bottom = !userSettings.verticalToolbar ? 0 : 70;
              
              
              //let margin_left = parseInt( (_app.currentStyle?.marginleft || document.defaultView?.getComputedStyle(_app, '')?.getPropertyValue('margin-left') || 0 ), 10);
              var clickCoordsX = getPosition(e).x;
              var clickCoordsY = getPosition(e).y;

              let windowWidth = window.innerWidth;
              let windowHeight = window.innerHeight;

              var transformX = 0;
              var transformY = 0;
              if ( (windowWidth - clickCoordsX - 5) < menuWidth ) {
                /*if (clickCoordsX - menuWidth > margin_left + 5)
                  transformX = 100;
                else*/
                  transformX =  Math.abs(Math.abs(clickCoordsX - windowWidth) - menuWidth) * 100 / menuWidth + 3;
              };

              if ( (windowHeight - e.clientY - margin_bottom - 5) < menuHeight ) {
                /*if ( e.clientY - menuHeight > margin_bottom && windowHeight - e.clientY > 0)
                  transformY = 100;
                else*/
                  transformY =  Math.abs(Math.abs(e.clientY - windowHeight) - menuHeight - margin_bottom) * 100 / menuHeight + 3;
              };

              /*console.log({windowWidth: windowWidth, windowHeight: windowHeight, clickCoordsX: clickCoordsX, clickCoordsY: clickCoordsY, transformX: transformX+"%", transformY: transformY+"%"})*/
              $( "#app" ).append(`
              <div id="debugHeroInfo" class="dropdown-content" style="z-index: 70; display: inline-block; max-height: 480px; top: ${clickCoordsY}px; left: ${clickCoordsX}px; width: ${menuWidth}px; transform: translate(-${transformX}%, -${transformY}%); border-top: thick solid var(--icon-bar-active); box-sizing: border-box;">
                <span style="width: 100%; font-size: 24px; text-align: center;"><b>${this.thisHeroTranslatedName(hero._id)}</b><b class="close" style="float: right; cursor: pointer; font-size: 30px; margin-right: -10px;" onclick="$('#debugHeroInfo').remove()">x</b></span>
                <a href="${e7dbLink}" target="_blank">${this.strings.view_on_e7db}</a>
                <a href="https://e7herder.com/tools/model-viewer#type=5,id=${hero.id}" target="_blank">${this.strings.view_hero_model}</a>
                <a onclick="
                  if (window.event.target.nodeName=='I') return;
                  app.risultati = [];
                  window.setWindow('calculate_window');
                  tastoDestro = 0; 
                  $('#debugHeroInfo').remove(); 
                  app.isLoadingResults=true; 
                  camperino.postMessage({type: 'friendship', HeroDB: app.HeroDB, myHeroesList: app.myHeroesList, campList: Object.keys(app.myHeroesList), locked: ['${key}'], classe: [], elemento: [], debuffs: [], buffs: [], AoE: false, noS1debuffs: false, noDebuffs: false, mustIncludeDispel: false, cartesianLock: [[],[],[],[]], preferenzeRisultati: app.customizedResuts, risultati: []});
                ">${this.strings.calculate_highest_friendship}<i style="float: right;" title="Help" onclick="app.helpWindow('app','friendship-farming'); tastoDestro = 0;  $('#debugHeroInfo').remove(); " class="fa fa-question-circle"></i></a>
                <span id="heroDetailsRight" style="width: 100% !important; padding: 0; overflow: scroll; position: relative; min-height: 50px;">
                  <i class="fa  fa-circle-notch fa-spin" style="font-size: 40px; position: absolute; top 40%; left: 40%;"></i>
                </span>
              </div>
              `);
              $.ajax({
                url: "https://api.epicsevendb.com/hero/" + hero._id + "?lang=" + this.lingua,
                type: 'GET',
                contentType: 'application/json',
                success: function (response) {
                  if (tastoDestro === 0) return;
                  if (document.getElementById("debugHeroInfo") === null ) return; // right click has been removed
                  var skills = response.results[0].skills;

                  for (var i = 0; i<skills.length; i++) {
                    for (var j = 0; j < skills[i].values.length; j++) {
                      var number = skills[i].values[j] <= 1 ? Math.round( skills[i].values[j]*100 ) + "%" : skills[i].values[j];
                      if (skills[i].enhanced_description) {
                        skills[i].enhanced_description = skills[i].enhanced_description.replace(/{{variable}}/i,'<font color="orangered">' + number + '</font>');
                      } else {
                        skills[i].description = skills[i].description.replace(/{{variable}}/i,'<font color="orangered">' + number + '</font>');
                      };
                    };
                  };

                  document.getElementById("heroDetailsRight").innerHTML = "";

                  $( "#heroDetailsRight" ).append(
                    `<span onclick="var menu = this.parentNode.children[3].childNodes; menu[0].style.display = 'inline-block'; menu[1].style.display = 'none'; menu[2].style.display = 'none';" style="background-image: url(${skills[0].assets.icon});" class="rightClickIconMenu"></span>` + 
                    `<span onclick="var menu = this.parentNode.children[3].childNodes; menu[0].style.display = 'none'; menu[1].style.display = 'inline-block'; menu[2].style.display = 'none';" style="background-image: url(${skills[1].assets.icon});" class="rightClickIconMenu"></span>` + 
                    (skills[2] ? `<span onclick="var menu = this.parentNode.children[3].childNodes; menu[0].style.display = 'none'; menu[1].style.display = 'none'; menu[2].style.display = 'inline-block';" style="background-image: url(${skills[2].assets.icon});" class="rightClickIconMenu"></span>` : "<span></span>") +
                    `<div style="padding: 0 16px 12px 16px; margin-top: -4px; background-color: var(--bg-color); max-height: 269px; overflow: scroll; overscroll-behavior: contain; box-sizing: border-box;">` +
                      `<div style="display: inline-block;"><p style="text-align: center"><b>${skills[0].name}</b></p><p>${(skills[0].enhanced_description || skills[0].description).replace(/\n/g,'<br>')}</p><p>${skills[0].soul_description ? "Soulburn:<br>" + skills[0].soul_description : ""}</p></div>` +
                      `<div style="display: none;"><p style="text-align: center"><b>${skills[1].name}</b></p><p>${(skills[1].enhanced_description || skills[1].description).replace(/\n/g,'<br>')}</p><p>${skills[1].soul_description ? "Soulburn:<br>" + skills[1].soul_description : ""}</p></div>` +
                      (skills[2] ? 
                          `<div style="display: none;"><p style="text-align: center"><b>${skills[2].name}</b></p><p>${(skills[2].enhanced_description || skills[2].description).replace(/\n/g,'<br>')}</p><p>${skills[2].soul_description ? "Soulburn:<br>" + skills[2].soul_description : ""}</p></div>` 
                          : "<div></div>"
                      ) +
                      `<p style="text-align: end; margin-bottom: 0;"><i>${self.strings.skills_not_enhanced}</i></p>` +
                    `</div>`
                  );
                },
                error: function (err) {
                  if (tastoDestro === 0) return;
                  console.log(err)
                  let error = "";
                  if (err.responseJSON) error = self.strings.e7api_missing_character; //"Couldn't find this character on EpicSevenDB";
                  else error = self.strings.e7api_couldnt_connect; //"Couldn't connect to EpicSevenDB.";
                  document.getElementById("heroDetailsRight").innerHTML = "";
                  document.getElementById("debugHeroInfo").style.borderColor = "red";
                  $( "#heroDetailsRight" ).append(
                    `<div style="padding: 12px 16px; margin-top: -4px; background-color: var(--bg-color)"><p style="text-align: center; border-color: red;">${error}</p></div>`
                  );
                }
              });
            }, 10);
          },
          menuLingua: function () {
            var langs = [
              {code: 'en', name: 'English', flag: ['https://upload.wikimedia.org/wikipedia/commons/e/e2/Flag_of_the_United_States_%28Pantone%29.svg','https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/320px-Flag_of_the_United_Kingdom.svg.png']},
              {code: 'kr', name: '한국어', flag: ['https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Flag_of_South_Korea.svg/320px-Flag_of_South_Korea.svg.png']},
              {code: 'cn', name: '汉语', flag: ['https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_the_People%27s_Republic_of_China.svg/320px-Flag_of_the_People%27s_Republic_of_China.svg.png']},
              {code: 'zht', name: '漢語', flag: ['https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Flag_of_the_Republic_of_China.svg/320px-Flag_of_the_Republic_of_China.svg.png']},
              {code: 'jp', name: '日本語', flag: ['https://upload.wikimedia.org/wikipedia/en/thumb/9/9e/Flag_of_Japan.svg/320px-Flag_of_Japan.svg.png']},
              {code: 'it', name: 'Italiano', flag: ['https://upload.wikimedia.org/wikipedia/en/thumb/0/03/Flag_of_Italy.svg/320px-Flag_of_Italy.svg.png']},
              {code: 'fr', name: 'Français', flag: ['https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Flag_of_Canada.svg/1024px-Flag_of_Canada.svg.png','https://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/320px-Flag_of_France.svg.png']},
              {code: 'es', name: 'Español', flag: ['https://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_Argentina.svg','https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Flag_of_Spain.svg/320px-Flag_of_Spain.svg.png']},
              {code: 'pt', name: 'Português', flag: ['https://upload.wikimedia.org/wikipedia/commons/0/05/Flag_of_Brazil.svg','https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Portugal.svg/320px-Flag_of_Portugal.svg.png']},
              {code: 'de', name: 'Deutsch', flag: ['https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_Germany.svg/320px-Flag_of_Germany.svg.png']},
              {code: 'th', name: 'ภาษาไทย', flag: ['https://upload.wikimedia.org/wikipedia/commons/a/a9/Flag_of_Thailand.svg']}
            ];
            var selection = "";
            for (var i = 0; i < langs.length; i++) {
              selection += 
              `<tr onclick="app.cambiaLingua('${langs[i].code}')" style="cursor: pointer; height: 70px; line-height: 100%;">
                <td style="width: 60%;">
                  <label class="check" style="display: inline-block; font-size: 30px; display: inline-block;">
                    <input type="checkbox" ${langs[i].code === this.lingua ? 'checked' : null}>
                    <span class="checkmark" style="border-radius: 100%;"></span>
                    ${langs[i].name}
                  </label>
                </td>
                <td style="width: 40%; text-align: end; white-space: nowrap;">
                  ${langs[i].flag.map(flag => {return `<img src="${flag}" height="50px" width="75px" style="margin-right: 10px;" style="border-radius: 16px;">`} ).join("")}
                </td>
                <td style="width: 10%; display: none;">
                  <label class="check" style="display: inline-block; font-size: 30px; display: inline; height: 100%; margin: 0; padding-left: 0;">
                    <input type="checkbox" ${langs[i].code === this.lingua ? 'checked' : ''}>
                    <span class="checkmark" style="border-radius: 100%;"></span>
                  </label>
                </td>
              </tr>`
            };
            $( "#settings_window" ).append(`
              <div id="menu_lingua">
                <div class="modal" style="display:block;">
                  <form class="modal-content  modal-small animate" style="max-width: 600px; padding: 0;" id="menu_lingua">
                    <!--<div style="display: none;">
                      <div class="modal-title">
                        ${this.strings.language}
                      </div>
                    </div>-->
                    <div style="text-align: initial; font-size: 30px; margin: 10px;">
                      <table style="width: 100%;">
                        ${selection}
                      </table>
                    </div>
                    <!--<div style="display: none;">
                      <button type="button" onclick="$('#menu_lingua').remove(); $('body').removeClass('modal-open')" class="modal-button">${this.strings.back_btn}</button>
                    </div>-->
                  </form>
                </div>
              </div>`
            );
            $("body").addClass("modal-open");
          },
          cambiaLingua: function (n) {
            if (n === this.lingua) {
               $('#menu_lingua').remove(); 
               $('body').removeClass('modal-open'); 
               return;
            }
            this.lingua = n;
            this.writeSettings();
            this.inizializzaione();
            this.impostaLingua();
            $('#menu_lingua').remove();
            $('body').removeClass('modal-open');
          },
          openCartesianLock: function (e) {
            this.isSelectingCartesian = e.toString();
            $("body").addClass("modal-open");
          },
          cartesianSlotRoster: function() {
            let tmp = [], n = this.isSelectingCartesian;
            for (var i in this.HeroDB) {
              //if (this.cartesian_lock.flat().includes(i) && !this.cartesian_lock[n].includes(i)) continue;
              if (this.myHeroesList[i]) tmp.push(i);
            };
            return tmp;
          },
          addToCartesianLock: function(e) {
            let n = this.isSelectingCartesian;
            this.cartesian_lock[n] = e;
            this.isSelectingCartesian = false;
            $("body").removeClass("modal-open");
          },
          removeCartesian_lock: function ( n, y) {
            if (this.cartesian_lock[n].includes(y))
              this.cartesian_lock[n].splice(this.cartesian_lock[n].indexOf(y), 1)
          },
          mostraSalvaRisultato: function (n) {
            try {
              $( "#calculate_window" ).append(`
                <div id="saveCamp" class="modal" style="display: block;">
                  <form class="modal-content modal-small animate" id="saveCamp">
                    <div class="imgcontainer">
                      <p>` + this.strings.morale + `: ` + this.risultati[n].morale + `</p>
                      <img src="` + this.getHeroAssets(this.HeroDB[this.risultati[n].team[0]]._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.HeroDB[this.risultati[n].team[0]]._id + `', 'onerror').icon;this.onerror=null;" style="height:55px;width:55px;">
                      <img src="` + this.getHeroAssets(this.HeroDB[this.risultati[n].team[1]]._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.HeroDB[this.risultati[n].team[1]]._id + `', 'onerror').icon;this.onerror=null;" style="height:55px;width:55px;">
                      <img src="` + this.getHeroAssets(this.HeroDB[this.risultati[n].team[2]]._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.HeroDB[this.risultati[n].team[2]]._id + `', 'onerror').icon;this.onerror=null;" style="height:55px;width:55px;">
                      <img src="` + this.getHeroAssets(this.HeroDB[this.risultati[n].team[3]]._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.HeroDB[this.risultati[n].team[3]]._id + `', 'onerror').icon;this.onerror=null;" style="height:55px;width:55px;">
                      <p>` + 
                        this.thisHeroTranslatedName(this.thisHeroData(this.risultati[n].migliorPG1)._id) + `: `+ this.translateTopics(this.risultati[n].opzioneMigliore1) + `<br>` +
                        this.thisHeroTranslatedName(this.thisHeroData(this.risultati[n].migliorPG2)._id) + `: `+ this.translateTopics(this.risultati[n].opzioneMigliore2) +
                      `</p>
                    </div>
                    <div id="campSavingError" style="text-align:center;color:red;"></div>
                    <div class="container">
                      <form id="save_camp_details">
                        <label for="camp_name"><b>` + this.strings.camp_name_field + `</b></label>
                        <input type="text" style="width: 100%;" placeholder="` + this.strings.camp_name_placeholder + `" name="camp_name" id="camp_name" required="">
                        <div style="text-align: center;">
                          <input type="checkbox" id="checkbox_normal" name="raid_difficulty">
                          <label for="checkbox_normal">`+ this.strings.normal + `</label>
                          <input type="checkbox" id="checkbox_hell" name="raid_difficulty">
                          <label for="checkbox_hell">` + this.strings.hell +`</label>
                        </div>
                        <div style="text-align: center;">
                          <input type="checkbox" id="checkbox_queen" name="raid_boss" style="position:relative;top:0px;display:none">
                          <label for="checkbox_queen" class="label noselect" style="position:relative;top:0px;"> <img src="https://cdn.glitch.com/97cf5510-4561-4fba-a2bd-849e3aed02ba%2FQueen-Azumashik-284x300.png?v=1590932065337" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">` + this.strings.queen + `</p></label>
                          <input type="checkbox" id="checkbox_karkanis" name="raid_boss" style="position:relative;top:0px;display:none">
                          <label for="checkbox_karkanis" class="label noselect" style="position:relative;top:0px;"> <img src="https://cdn.glitch.com/97cf5510-4561-4fba-a2bd-849e3aed02ba%2FKarkanis-284x300.png?v=1590932065109" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">` + this.strings.karkanis + `</p></label>
                          <input type="checkbox" id="checkbox_juleeve" name="raid_boss" style="position:relative;top:0px;display:none">
                          <label for="checkbox_juleeve" class="label noselect" style="position:relative;top:0px;"> <img src="https://cdn.glitch.com/97cf5510-4561-4fba-a2bd-849e3aed02ba%2FJuleeve-284x300.png?v=1590932065054" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">` + this.strings.juleeve + `</p></label>
                          <input type="checkbox" id="checkbox_vera" name="raid_boss" style="position:relative;top:0px;display:none">
                          <label for="checkbox_vera" class="label noselect" style="position:relative;top:0px;"> <img src="https://cdn.glitch.com/97cf5510-4561-4fba-a2bd-849e3aed02ba%2FSecretary-Vera-284x300.png?v=1590932064989" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">` + this.strings.vera + `</p></label>
                          <input type="checkbox" id="checkbox_arakahan" name="raid_boss" style="position:relative;top:0px;display:none">
                          <label for="checkbox_arakahan" class="label noselect" style="position:relative;top:0px;"> <img src="https://cdn.glitch.com/97cf5510-4561-4fba-a2bd-849e3aed02ba%2FDevourer-Arakahan-284x300.png?v=1590932064956" style="position:relative;top:0px;height:60px;width:60px;" /><p style="position:relative;text-align:center;">` + this.strings.arakahan + `</p></label>
                        </div>
                        <button type=submit onclick="return app.salvaRisultato(` + n + `)" class="modal-button">` + this.strings.save + `</button>
                        <button type=button onclick="$('#saveCamp').remove(); $('body').removeClass('modal-open')" class="modal-button">` + this.strings.canc_btn + `</button>
                      </form>
                    </div>
                  </form>
                </div>
              `);
              $("body").addClass("modal-open");
              $('#camp_name').focus();
            } catch (err) {
              $('body').removeClass('modal-open');
            }
          },
          salvaRisultato: function (n) {
            try {
              var $form = $("#saveCamp");
              var campName = $('#camp_name', $form).val().replace(/  +/g,"").trim();
              if (campName && campName != "" && campName.indexOf("@_#") == -1) {
                if (!this.savedCamps[campName]) {
                  var normal = false;
                  var hell = false;
                  var queen = false;
                  var karkanis = false;
                  var juleeve = false;
                  var vera = false;
                  var arakahan = false;
                  if (document.getElementById("checkbox_normal").checked === true ) normal = true;
                  if (document.getElementById("checkbox_hell").checked === true ) hell = true;
                  if (document.getElementById("checkbox_queen").checked === true) queen = true;
                  if (document.getElementById("checkbox_karkanis").checked === true ) karkanis = true;
                  if (document.getElementById("checkbox_juleeve").checked === true ) juleeve = true;
                  if (document.getElementById("checkbox_vera").checked === true ) vera = true;
                  if (document.getElementById("checkbox_arakahan").checked === true ) arakahan = true;
                  var save = this.risultati.slice(n,n+1)[0];
                  save.normal = normal;
                  save.hell = hell;
                  save.queen = queen;
                  save.karkanis = karkanis;
                  save.juleeve = juleeve;
                  save.vera = vera;
                  save.arakahan = arakahan;

                  this.savedCamps[campName] = this.risultati[n];
                  var sendData = {morale: this.risultati[n].morale, team: this.risultati[n].team,  normal: normal, hell: hell, queen: queen, karkanis: karkanis, juleeve: juleeve, vera: vera, arakahan: arakahan};

                  $('#saveCamp').remove();
                  $('body').removeClass('modal-open');
                  localStorage.setItem('savedCamps', JSON.stringify(this.savedCamps) );
                  this.displaySavedCamps = Object.keys(this.savedCamps); // aggionra la lista da visulizzare
                  sendTeamUsageStatistics({function: "add", data: [sendData]}); // send team comp to server for stats
                  snackbarMessage(campName + ` ` + this.strings.saved_message)
                } else {
                  $("#campSavingError").text(this.strings.error_name_in_use);
                };
              } else if (campName.indexOf("@_#") != -1) {
                $("#campSavingError").text("The sequence @_# can't be used");  
              } else {
                $("#campSavingError").text(this.strings.error_no_name_provided);
              };
            } catch (err) {
              console.log(err)
            }; 
            return false;
          },
          eliminaRisultatoSalvato: function (campName) {
            try {
                campName = campName.replace(/@_#3#9#;/g,"'").replace(/@_#3#4#;/g,'"').replace(/@_#9#6#;/g,'`'); // avoid errors during deletion
                sendTeamUsageStatistics({function: "remove", data: [this.savedCamps[campName]]}); // send team comp to server for stats
                delete this.savedCamps[campName];
                $('#savedCamp').remove();
                $('body').removeClass('modal-open');
                localStorage.setItem('savedCamps', JSON.stringify(this.savedCamps) );
                this.displaySavedCamps = Object.keys(this.savedCamps); // aggionra la lista da visulizzare

                snackbarMessage(campName + ` ` + this.strings.deleted_message);
            } catch (err) {
              console.log("Error while removing camp")
            };
          },
          mostraRisultatoSalvato: function (campName) {
            for (var i in this.savedCamps[campName].team) {
              this.savedCamps[campName].team[i] = this.savedCamps[campName].team[i].toLowerCase().replace(/ /g,"-").replace(/&/g,"").replace(/'/g,"");
            };
            this.savedCamps[campName].migliorPG1 = this.savedCamps[campName].migliorPG1.toLowerCase().replace(/ /g,"-").replace(/&/g,"").replace(/'/g,"");
            this.savedCamps[campName].migliorPG2 = this.savedCamps[campName].migliorPG2.toLowerCase().replace(/ /g,"-").replace(/&/g,"").replace(/'/g,"");
            $( "#my_teams_window" ).append(`
              <div id="savedCamp" class="modal" style="display:block;">
                <form class="modal-content modal-small animate" id="savedCamp">
                  <div class="imgcontainer">
                    <span onclick="app.eliminaRisultatoSalvato('` + campName.replace(/'/g,"@_#3#9#;").replace(/"/g,'@_#3#4#;').replace(/`/g,'@_#9#6#;') + `')"><i class="fa fa-trash close" style="color: var(--font-color);"></i></span>
                    <p>` + this.strings.morale + `: ` + this.savedCamps[campName].morale + `</p>
                    <img src="`+ this.getHeroAssets(this.thisHeroData( this.savedCamps[campName].team[0] )._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.thisHeroData( this.savedCamps[campName].team[0] )._id + `', 'onerror').icon;this.onerror=null" style="height:55px;width:55px;">
                    <img src="`+ this.getHeroAssets(this.thisHeroData( this.savedCamps[campName].team[1] )._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.thisHeroData( this.savedCamps[campName].team[1] )._id + `', 'onerror').icon;this.onerror=null" style="height:55px;width:55px;">
                    <img src="`+ this.getHeroAssets(this.thisHeroData( this.savedCamps[campName].team[2] )._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.thisHeroData( this.savedCamps[campName].team[2] )._id + `', 'onerror').icon;this.onerror=null" style="height:55px;width:55px;">
                    <img src="`+ this.getHeroAssets(this.thisHeroData( this.savedCamps[campName].team[3] )._id).icon + `" onerror="this.src=app.getHeroAssets('` + this.thisHeroData( this.savedCamps[campName].team[3] )._id + `', 'onerror').icon;this.onerror=null" style="height:55px;width:55px;">
                    <p>` + 
                      this.thisHeroTranslatedName(this.thisHeroData(this.savedCamps[campName].migliorPG1)._id) + `: `+ this.translateTopics(this.savedCamps[campName].opzioneMigliore1) + `<br>` +
                      this.thisHeroTranslatedName(this.thisHeroData(this.savedCamps[campName].migliorPG2)._id) + `: `+ this.translateTopics(this.savedCamps[campName].opzioneMigliore2) +
                    `</p>
                  </div>
                  <div class="container">
                    <button type="button" onclick="$('#savedCamp').remove(); $('body').removeClass('modal-open');" class="modal-button">` + this.strings.back_btn + `</button>
                  </div>
                </form>
              </div>
            `);
            $("body").addClass("modal-open");
          },
          modalGenerateURL: function (campName) {
            $( "#settings_window" ).append(`
              <div id="url_generator" class="modal" style="display:block;">
                <div class="modal-content modal-small animate">
                  <div class="imgcontainer">
                    <div id="url_container" class="box_advanced_settings" style="display: block; width:100%; max-height: 250px; padding: 20px;  position: relative; overflow-x: auto; font-size: 16px; word-break: break-all;background-color: rgb(0,0,0,0.4);box-sizing: border-box;">` + 
                      generateUrl(this.myHeroesList) + 
                   `</div>
                    <button type="button" onclick="copyText('url_container')" class="button_login">` + this.strings.copia + `</button>
                    <br>` + this.strings.url_usage_help + `<br><br>
                  </div>
                  <div class="container">
                    <button type="button" onclick="$('#url_generator').remove(); $('body').removeClass('modal-open');" class="modal-button" style="width:100%">` + this.strings.back_btn + `</button>
                  </div>
                </div>
              </div>
            `);
            $("body").addClass("modal-open");
          },
          getSavedTeamsStats: function() {
            self = this;
            var refreshButton = document.getElementById("refreshStats");
            refreshButton.style.display = "none";
            if (document.getElementById("stats_table")) $("#stats_table").remove();
            $.ajax({
              url: "https://ceciliabotgithub.glitch.me/team_statistics",
              type: 'GET',
              contentType: 'application/json',
              success: function (response) {
                var toPrint = "";
                var toPrintChar = "";
                var usiTop400 = 0;
                if (response.data.length>0) {
                  for (var i = 0; i < response.data.length; i++) {
                    if (self.HeroDB[response.data[i].team[0]]) {
                      usiTop400 += response.data[i].usi;
                      toPrint += "<tr>" +  
                          `<td style='padding-top: 15px; padding-bottom:10px'><img src="` + self.getHeroAssets(self.HeroDB[response.data[i].team[0]]._id).icon + `" onerror="this.onerror=null;this.src=app.getHeroAssets('` + self.HeroDB[response.data[i].team[0]]._id + `', 'onerror').icon;" style="height:55px;width:55px;"></td>` +
                          `<td style='padding-top: 15px; padding-bottom:10px'><img src="` + self.getHeroAssets(self.HeroDB[response.data[i].team[1]]._id).icon + `" onerror="this.onerror=null;this.src=app.getHeroAssets('` + self.HeroDB[response.data[i].team[1]]._id + `', 'onerror').icon;" style="height:55px;width:55px;"></td>` +
                          `<td style='padding-top: 15px; padding-bottom:10px'><img src="` + self.getHeroAssets(self.HeroDB[response.data[i].team[2]]._id).icon + `" onerror="this.onerror=null;this.src=app.getHeroAssets('` + self.HeroDB[response.data[i].team[2]]._id + `', 'onerror').icon;" style="height:55px;width:55px;"></td>` +
                          `<td style='padding-top: 15px; padding-bottom:10px'><img src="` + self.getHeroAssets(self.HeroDB[response.data[i].team[3]]._id).icon + `" onerror="this.onerror=null;this.src=app.getHeroAssets('` + self.HeroDB[response.data[i].team[3]]._id + `', 'onerror').icon;" style="height:55px;width:55px;"></td>` +
                          "<td style='width:50vw; padding-top: 15px; padding-bottom:10px'> <div class='histogram_bar' style='width:" + response.data[i].usi/response.totale*100 + "%;'><span>" + Math.round(( (response.data[i].usi/response.totale*100)+ Number.EPSILON) * 100) / 100 + " %</span></div></td>" +
                          "<td style='text-align: center; padding-top: 15px; padding-bottom:10px; border-right: thin;'>" + response.data[i].morale + "</td>" +
                          "<td style='text-align: center; padding-top: 15px; padding-bottom:10px'>" + response.data[i].usi + "</td></tr>";
                    };
                  };
                  for (var i = 0; i < response.characters.length; i++) {
                    if (self.HeroDB[response.characters[i].character]) {
                      toPrintChar += "<tr>" +  
                        `<td style='padding-top: 15px; padding-bottom:10px'><img src="` + self.getHeroAssets(self.HeroDB[response.characters[i].character]._id).icon + `" onerror="this.onerror=null;this.src=app.getHeroAssets('` + self.HeroDB[response.characters[i].character]._id + `', 'onerror').icon;" style="height:55px;width:55px;"></td>` +
                        "<td style='width: 80vw; padding-top: 15px; padding-bottom:10px'> <div class='histogram_bar' style='width:" + response.characters[i].usi/response.totale*100 + "%;'><span>" + Math.round((( response.characters[i].usi/response.totale*100)+ Number.EPSILON) * 100) / 100 + " %</span></div></td>" +
                        "<td></td>" +
                        "<td style='text-align: center; padding-top: 15px; padding-bottom:10px'>" + response.characters[i].usi +"</td></tr>";
                    };
                  };
                  if (usiTop400 < response.totale) {
                    toPrint += "<tr>" +
                      "<td colspan='4' style='text-align: center;'>" + self.strings.others + "</td>" +
                      "<td style='width:50vw; padding-top: 15px; padding-bottom:10px'> <div class='histogram_bar' style='width:" + (response.totale-usiTop400)/response.totale*100 + "%;'><span>" + Math.round(( ( (response.totale-usiTop400)/response.totale*100)+ Number.EPSILON) * 100) / 100 + " %</span></div></td>" +
                      "<td></td>" +
                      "<td style='text-align: center; padding-top: 15px; padding-bottom:10px'>" + (response.totale-usiTop400) + "</td></tr>";
                  };

                } else {
                  toPrint = "<td>No data</td>";
                  toPrintChar = "";
                };
                refreshButton.style.display = "";
                $('#char_tab_stats').removeClass('activetab');
                $('#team_tab_stats').addClass('activetab');
                $( "#saved_teams_stats").append(`<table id="stats_table" style="width: 100%; background-color: var(--bg-color-secondary); padding: 10px; border-radius: 0 0 12px 12px;"><tbody id="teams_stats_tbody">
                  <th colspan="4">${self.strings.team}</th>
                  <th></th>
                  <th style="white-space: nowrap;">${self.strings.morale}</th>
                  <th style="white-space: nowrap;">${self.strings.teams}</th>
                  ` + toPrint + `</tbody>
                  <tbody id="char_stats_tbody" style="display: none;">
                  <th></th>
                  <th></th>
                  <th style="width: 20px;"></th>
                  <th style="white-space: nowrap;">${self.strings.teams}</th>
                  ` + toPrintChar + `</tbody></table>`);
              },
              error: function(jqXHR, textStatus, errorThrown) {
                refreshButton.style.display = "";
                $( "#saved_teams_stats").append(`<table id="stats_table"><td style="text-align: center;">Error while retirving data.<br> Please retry.</td></table>`);
                snackbarMessage(`failed to retrive data`);
              }
            });
          },
          helpWindow: function (sezione, argomento) {
            var titolo, contenuto;
            switch (argomento) {
              case 'add_heroes_help':
                titolo = self.strings.aggiungi;
                contenuto = self.strings.add_heroes_help;
                break;
              case 'manage_heroes_help':
                titolo =self.strings.manage_heroes;
                contenuto = self.strings.manage_heroes_help;
                break;
              case 'friendship-farming':
                titolo =self.strings.calculate_highest_friendship;
                contenuto = self.strings.calculate_highest_friendship_help;
                break;
              case 'advanced_settings':
                titolo =self.strings.impostazioni_avanzate;
                contenuto = self.strings.advanced_settings_help;
                break;
              case 'multi-lock':
                titolo =self.strings.multilock;
                contenuto = self.strings.multilock_help;
                break;
              case 'results_help':
                titolo =self.strings.risultati;
                contenuto = self.strings.results_help;
                break;
              default:
                titolo = "";
                contenuto = "";
            };

            $( "#" + sezione).append(`
              <div id="help_menu" class="modal" style="display:block;">
                <form class="modal-content modal-small modal-three-parts animate" id="savedCamp">
                  <div>
                    <span class="modal-title">` + titolo + `
                    </span>
                  </div>
                  <div>
                    <div class="modal-text">` + contenuto + `
                    </div>
                  </div>
                  <div>
                    <button type="button" onclick="$('#help_menu').remove(); $('body').removeClass('modal-open');" class="modal-button">` + this.strings.back_btn + `</button>
                  </div>
                </form>
              </div>
            `);
            $("body").addClass("modal-open"); //prevent body from scrolling while modal is open
          },
          setDisplayStyle: function(layout, sezione) {
            var add_window = document.getElementById("pulsanti_display_add_window").getElementsByClassName("search_hero_filter");
            add_window[0].className = "search_hero_filter";
            add_window[1].className = "search_hero_filter";
            var manage_window = document.getElementById("pulsanti_display_manage_window").getElementsByClassName("search_hero_filter");
            manage_window[0].className = "search_hero_filter";
            manage_window[1].className = "search_hero_filter";
            if (layout.value == "grid") {
                add_window[0].className += " active";
                manage_window[0].className += " active";
            } else if (layout.value == "list") {
                add_window[1].className += " active";
                manage_window[1].className += " active";
            };
            this.displayStyle = layout.value;
          },
          sortHeroes: function (sortBy, a, b) {
            return this.thisHeroData(a)[sortBy] > this.thisHeroData(a)[sortBy] ? this.thisHeroData(a).name < this.thisHeroData(a).name : -1
          },
          filtroTuttiGliEroi: function (button, listToModify) {
            self = this;
            var tmpArray, pulsantiIn, filtro = {};
            if (listToModify === "AllHeroes" || listToModify == undefined)  { 
              tmpArray = this.sortedHeroDB.slice(); // slice per creare una copia e non modificare l'originale
              pulsantiIn = document.getElementById("add_window"); // determina in che sezione sono i pulsanti
              //if (button.className == "search_hero_filter") 
              filtro["ricerca"] = document.getElementById("inputInTuttiGliEroi").value; // ottieni il testo digitato nella casella
            } else if (listToModify === "MyHeroes")  {
              tmpArray = Object.keys(this.myHeroesList);
              filtro["ricerca"] =  document.getElementById("inputInMyHeroes").value; // ottieni il testo digitato nella casella
              pulsantiIn = document.getElementById("manage_window"); // determina in che sezione sono i pulsanti
            };
            if (filtro.ricerca == undefined) filtro.ricerca = "";
            var pulsanti = pulsantiIn.getElementsByClassName(button.className);
            for (var i = 0; i < pulsanti.length; i++) {
              if (pulsanti[i].className.indexOf("active") != -1) {
                filtro[pulsanti[i].name] = pulsanti[i].value;
                if (pulsanti[i].name == button.name) pulsanti[i].className = button.className; // rimuove la class "active"
              };
            };
            button.className = button.className.replace(/active/gi,"");
            button.className += " active"; // attiva questo pulsante
            filtro[button.name] = button.value; // attualizza il filtro
            //imposta la nuova array da visualizzare
            for (var i = 0; i < tmpArray.length;i++) {
              if ((this.HeroDB[tmpArray[i]].role != filtro.filter_class && filtro.filter_class != "*") || 
                  (this.HeroDB[tmpArray[i]].attribute != filtro.filter_element && filtro.filter_element != "*") || 
                  (this.HeroDB[tmpArray[i]].rarity != filtro.filter_rarity && filtro.filter_rarity != "*") ||
                  (filtro.filter_gia_aggiunti == "true" && this.myHeroesList[tmpArray[i]] ) ||
                  (this.thisHeroTranslatedName(this.thisHeroData(tmpArray[i])._id).toLowerCase().indexOf(filtro.ricerca.toLowerCase()) === -1 && this.thisHeroData(tmpArray[i]).name.toLowerCase().indexOf(filtro.ricerca.toLowerCase()) === -1)
              ) {
                 tmpArray.splice(tmpArray.indexOf(tmpArray[i]), 1);
                 i--
              };
            };
            if (listToModify === "AllHeroes" || listToModify == undefined)  { 
                this.displayList = tmpArray;
                //tmpArray.length = 0;
            } else if (listToModify === "MyHeroes")  { 
                if (filtro["filter_locked_only"] == "true") tmpArray = this.locked;
                this.displayMyHeroes = tmpArray;
                //tmpArray.length = 0;
            };
          },
          personalizzaRisultati: function () {
            var risultati = { numeroMassimo: true, n: 200, noImmagini: false, minMorale: false, morale: 0, lockedMatter: false, advMuteLocked: false }
            checkNumeroMassimo = document.getElementById("numeroRisultatiMassimo");
            valoreRisultatiMassimo = document.getElementById("n_risultati");
            checkMoraleMinimo = document.getElementById("moraleMinimo");
            valoreMoraleMinimo = document.getElementById("n_moraleMinimo");
            //checkImmagini = document.getElementById("disattivaImmaingiRisultati");
            if (checkNumeroMassimo.checked) {
              risultati.numeroMassimo = true;
              valoreRisultatiMassimo.disabled = false;
            } else {
              risultati.numeroMassimo = false;
              valoreRisultatiMassimo.disabled = true;
            };
            if (checkMoraleMinimo.checked) {
              risultati.minMorale = true;
              valoreMoraleMinimo.disabled = false;
            } else {
              risultati.minMorale = false;
              valoreMoraleMinimo.disabled = true;
            };
            if (document.getElementById("includi_locked_in_advanced_settings").checked) risultati.lockedMatter = true;
            //if (checkImmagini.checked) {
            //  risultati.noImmagini = true;
            //};
            if (document.getElementById("adv_mute_locked_heroes").checked) risultati.advMuteLocked = true;
            
            if (!isNaN(parseInt(valoreRisultatiMassimo.value)) && parseInt(valoreRisultatiMassimo.value) > 0 ) {
              risultati.n = parseInt(valoreRisultatiMassimo.value)
              if (parseInt(valoreRisultatiMassimo.value) > 10000) {
                risultati.n = 10000;
                valoreRisultatiMassimo.value = 10000;
              }
            } else {
              risultati.n = 200;
            };

            if (!isNaN(parseInt(valoreMoraleMinimo.value)) && parseInt(valoreMoraleMinimo.value) <= 52 ) {
              risultati.morale = parseInt(valoreMoraleMinimo.value)
            } else {
              risultati.morale = 0
            };
            if (risultati.numeroMassimo === false && risultati.minMorale === false) {risultati.numeroMassimo = true; risultati.n = 200;}
            if (risultati.numeroMassimo === false && risultati.minMorale === true) {risultati.numeroMassimo = true; risultati.n = 200;} // force a limit of 200 if only min morale is checked to avoid large memory usage
            this.customizedResuts = risultati;
          },
          editClassQuantity: function (e) {
            var target = e.parentNode, _classe = e.parentNode.attributes.value.value, n = 0;
            if (!this.classe[_classe]) this.classe[_classe] = 0
            if (e.className === "incrementa"){
              var length = 0
              Object.values(this.classe).forEach( n => length += Math.max(0, n) );
              if (length > 3 && this.classe[_classe] > -1) return snackbarMessage(this.strings["team_size_exceeded"]);
              this.classe[_classe] ++;
            } else if (e.className === "decrementa") {
              if (this.classe[_classe] === -1) return
              this.classe[_classe]--
            }

            target.firstElementChild.innerHTML = this.classe[_classe];
            if (this.classe[_classe]===0) target.firstElementChild.style.display = "none"
            else target.firstElementChild.style.display = ""
          },
          editAttributeQuantity: function (e) {
            var target = e.parentNode, _classe = e.parentNode.attributes.value.value, n = 0;
            if (!this.elemento[_classe]) this.elemento[_classe] = 0
            if (e.className === "incrementa"){
              var length = 0
              Object.values(this.elemento).forEach( n => length += Math.max(0, n) );
              if (length > 3 && this.elemento[_classe] > -1) return snackbarMessage(this.strings["team_size_exceeded"]);
              this.elemento[_classe] ++;
            } else if (e.className === "decrementa") {
              if (this.elemento[_classe] === -1) return
              this.elemento[_classe]--
            }

            target.firstElementChild.innerHTML = this.elemento[_classe];
            if (this.elemento[_classe]===0) target.firstElementChild.style.display = "none"
            else target.firstElementChild.style.display = ""
          },
          aggiornaImposatazioniAvanzate: function () {
                this.debuffs = [];
                this.buffs = [];

                //Raccogli le impostazioni avanzate
                var debuffs_checkbox = document.getElementsByName("debuff");
                var buffs_checkbox = document.getElementsByName("buff");
                //for(var i = 0; i < classi.length; i++)  
                //{  
                //    if (classi[i].checked) this.classe.push(classi[i].value);
                //};
                for(var i = 0; i < debuffs_checkbox.length; i++)  
                {  
                    if (debuffs_checkbox[i].checked) this.debuffs.push(parseInt(debuffs_checkbox[i].value));
                }; 
                for(var i = 0; i < buffs_checkbox.length; i++)  
                {  
                    if (buffs_checkbox[i].checked) this.buffs.push(parseInt(buffs_checkbox[i].value));
                }; 

                if ($('#AoE').is(":checked"))
                {
                    this.AoE = true;
                } else this.AoE = false;

                if ($('#noS1debuffs').is(":checked"))
                {
                    this.noS1debuffs = true;
                } else this.noS1debuffs = false;

                if ($('#noDebuffs').is(":checked"))
                {
                    this.noDebuffs = true;
                } else this.noDebuffs = false;

                if (document.getElementById("mustIncludeDispel").checked)
                {
                  this.mustIncludeDispel = true;
                } else this.mustIncludeDispel = false;

                if (document.getElementById("mustIncludeCleanser").checked)
                {
                  this.mustIncludeCleanser = true;
                } else this.mustIncludeCleanser = false;
            },
            impostaLingua: function () {
              var lingua = JSON.parse(localStorage.getItem('Settings') ? localStorage.getItem('Settings') : '{"lingua":"*"}').lingua;
              if (lingua == undefined) lingua = "*";
              try {
                if (lingua === "*") { // detect browser language
                  switch ( (navigator.language || navigator.userLanguage).split("-")[0] ) { // check browser setting and select language
                    case 'it':
                      lingua = "it";
                      break;
                    case 'fr':
                      lingua = "fr";
                      break;
                    case 'de':
                      lingua = "de";
                      break;
                    case 'pt':
                      lingua = "pt";
                      break;
                    case 'es':
                      lingua = "es";
                      break;
                    case 'ja':
                      lingua = "jp";
                      break;
                    case 'ko':
                      lingua = "kr";
                      break;
                    case 'th':
                      lingua = "th";
                      break;
                    case 'zh':
                      var langCode = navigator.language || navigator.userLanguage;
                      if (langCode === "zh-TW" || langCode === "zh-HK" || langCode === "zh-MO") lingua = "zht"
                      else lingua = "cn";
                      break;
                    default:
                      lingua = "en";
                  };
                };
              } catch (err) {
                lingua = "en"
              };
              this.lingua = lingua;
              
              //change titile and meta info
              if (this.lingua == "zht") {
                document.title = "第七史詩 露營模擬器";
                document.getElementsByTagName('meta')["keywords"].content = "第七史詩露營， 第七史詩露營模擬器，e7露營模擬器，第七史詩迷宮心情計算，第七史詩迷宮，e7迷宮心情計算";
                document.getElementsByTagName('meta')["description"].content = "第七史詩迷宮心情計算器，添加你的英雄算出符合你需求的最佳隊伍組合！";
              } else if (this.lingua == "cn") {
                document.title = "第七史诗 露营模拟器";
                document.getElementsByTagName('meta')["keywords"].content = "第七史诗露营， 第七史诗露营模拟器，e7露营模拟器，第七史诗迷宫心情计算，第七史诗迷宫，e7迷宫心情计算";
                document.getElementsByTagName('meta')["description"].content = "第七史诗迷宫心情计算器，添加你的英雄算出符合你需求的最佳队伍组合！";
              } else if (this.lingua == "fr") {
                document.title = "Simulateur de Camp E7";
                document.getElementsByTagName('meta')["keywords"].content = "camping epic seven, simulateur de camping epic 7, simulateur de camp e7, calculateur de moral epic 7, raid e7, raid epic seven";
                document.getElementsByTagName('meta')["description"].content = "Calculateur de moral E7. Ajoutez votre héros pour trouver la meilleure combinaison d'équipe avec un moral élevé!";
              } else {
                document.title = "E7 Camp Simulator";
                document.getElementsByTagName('meta')["keywords"].content = "epic seven camping, epic 7 camping simulator, e7 camp simulator, epic 7 morale calculator, e7 raid, epic seven raid";
                document.getElementsByTagName('meta')["description"].content = "Epic Seven Camping Simulator for Raid and Labyrinth. Add your roster to find the best team combination with high morale!";
              };

              if (this.lingua == "it") {
                this.strings = {
                  welcome: "Benvenuto",
                  whats_new: "Novità",
                  instructions: "Istruzioni",
                  websites: "Pagine",
                  credits: "Credits",
                  messaggio_di_benvenuto: "Benvenuto su Epic Seven Camp simulator",
                  data_by: "Data by EpicSevenDB",
                  all: "All",
                  sort: "Ordina",
                  filter: "Filtro",
                  modified: "Modifica",
                  name: "Nome",
                  ingame_id: "ID gioco",
                  remove_displayed_heroes: "Rimuovi questi eroi",
                  add_displayed_heroes: "Aggiungi questi eroi",
                  confirm_remove_heroes: "Sei sicuro di voler rimuovere <N> eroi dalla tua lista?",
                  confirm_add_heroes: "Sei sicuro di voler aggiungere <N> eroi dalla tua lista?",
                  aggiungi: "Aggiungi eroe",
                  i_tuoi_eroi: "I tuoi eroi",
                  search: "Cerca",
                  cant_lock_more_heroes: "Hai già 4 eroi in squadra",
                  impostazioni_avanzate: "Impostazioni Avanzate",
                  warn_tsize_adv_title: "Hai un sacco di eroi e nessun eroe bloccato",
                  warn_tsize_adv_details: "Attivando le impostazioni avanzate aumenterà il tempo richiesto per il calcolo delle combinazioni. \nPuoi ridurre il tempo richiesto per il calcolo bloccando un personaggio.",
                  numero_massimo_risultati: "Numero massimo di risultati (max 10.000)",
                  morale_minimo_risultati: "Morale minimo",
                  includi_locked_in_adv: "Gli eroi bloccati contano al fine del raggiungimento delle condizioni avanzate",
                  adv_mute_locked_heroes: "Discard team if a topic is held by a locked hero",
                  disabilita_immagini_in_risultati: "Disabilita avatar dei personaggi nei risultati (consigliato se si richiedono tanti risultati)",
                  deve_contenere_AoE: "Team deve contenere AoE",
                  no_s1_debuffs: "No S1 Debuffs (Esclusi: Provoke, Sleep, Stun e Poison)",
                  no_debuffs: "No Debuffs (Esclusi: Provoke, Sleep, Stun e Poison)",
                  must_include_dispel: "Team deve contenere dispel (Rimuovi o riduci la durata dei buff dal nemico)",
                  must_include_cleanser: "Team deve contenere cleanser (Rimuovi o riduci la durata dei debuff)",
                  classe: "Classe",
                  attribute: "Attributo",
                  rarity: "Rarità",
                  knight: "Knight",
                  warrior: "Warrior",
                  thief: "Thief",
                  ranger: "Ranger",
                  mage: "Mage",
                  "soul-weaver": "Soul Weaver",
                  fire: "Fire",
                  ice: "Ice",
                  earth: "Earth",
                  light: "Light",
                  dark: "Dark",
                  elemento: "Elemento",
                  buff: "Buff",
                  debuff: "Debuff",
                  combinations: "Combinazioni possibili",
                  multilock: "Multi-lock (Cartesian Product)",
                  multilock_slot: "Slot",
                  add_to_slot: "Aggiungi a questo slot",
                  add_selection: "Aggiungi selezionati",
                  seleziona: "Seleziona",
                  deselect_all : "Deseleziona tutto",
                  possibili_combinazioni: "Combinazioni:",

                  //Help window
                  add_heroes_help: "Tap or click the portrait of a hero to add that hero to your roster.<br>\
                            Heroes in your roster will be used to calculate all possible combinations and return the best 200 combinations.<br>\
                            You can add as many heroes as you wish but the time needed to calculate all possible combinations will also increase.<br>\
                            Your roster will be saved and can be used everytime you visit this page without the need to add each hero everytime!<br>\
                            <br>\
                            If you are using the \"List\" display mode tap the \"+\" symbol to add a hero to your roster",
                  manage_heroes:"Manage Heroes",
                  manage_heroes_help:"In this window you can view all the heroes currently in your roster.<br>\
                            You can remove a hero by clicking the \"x\" at the bottom of the hero's portrait.<br>\
                            You can lock a hero by clicking he's portrait, a lock symbol will appear near the portrait. A locked hero will appear in every team in the results page.<br>\
                            You can calculate all the camping results for the current roster by clicking the bonfire icon in the toolbar or click the book icon to add advance settings.",  
                  calculate_highest_friendship_help: "Calculate all the combinations that give the selected character the highest friendship;<br>\
                            Team morale will not be calculated and the morale displayed in the results window will be replaced by the character's friendship (title is morale but please ignore that).<br>\
                            Advanced settings will be ignored and all the combinations will be generated using your roster, make sure you have at least 4 characters in your roster!",
                  advanced_settings_help:"Here you can costumize your camp results.<br>\
                            <b style=\"color:red\">Locked heroes are not subject to these restrictions</b><br><br>\
                            You can select as many as you want but keep in mind time size while doing so.<br>\
                            For example if you lock 5 classes or 5 elements you will get a team size error.<br>\
                            Because locked heroes ignore advanced settings if you lock \"Tamarinne\" and select Soul weaver as a class you will get \"Tamarinne\" + another Soul weaver in every team. The same thing applies to Buffs and Debuffs<br>",
                  multilock_help:"Each slot is a space in your team, on each slot you can add as many heroes as you wish.<br>\
                            Only one of the Heroes locked for each slot will be in the results. The same hero can't be added on multiple slots.<br>\
                            Empty slots will be filled with the remaining heroes in your roster.<br>\
                            If you use all your heroes to fill 3 or less slots and no heroes are left to fill the remaining slots you will get a \"not enough heroes left\" error.<br>\
                            Slots that are left empty will be subject of restrictions from advanced settings.<br><br>\
                            Locked heroes in one of the slots will ignore advanced settings.<br>\
                            If you fill all the slots and select any advanced settings you will get a \"team size exceeded\" error or 0 results.<br>\
                            This option is useful to create costum rules, for example you can put all your knights in 1 slot and you will get a knight for each team in the results!",
                  results_help : "Here are displayed the best 200 combinations for your roster and current advanced settings.<br>\
                            You need at least 4 heroes in your current roster for any result to be displayed.<br>\
                            You can click the floppy disk icon to save a specific team composition (you will be prompted to input a name for that team), your saved teams will be displayed in the settings window.",

                  //Results window
                  risultati: "Risultati",
                  morale: "Morale",
                  team: "Team",
                  topics: "Topics",
                  abort_calculation: "Annulla operazione",
                  confirm_worker_termination: "Sei sicuro di voler annullare l'operazione?",
                  notification_title: "E7 Camp Simulator",
                  notification_ready: "I tuoi team sono pronti!",
                  results_error: "Errore",
                  team_size_exceeded: "Dimensione team superata!",
                  not_enough_heroes: "Nessun eroe rimanente da inserire nei rimanenti slot!",
                  locked_sc_normal_err: "Bloccati SC e eroe normale",

                  ///Result saving window:
                  camp_name_field: "Nome camp",
                  camp_name_placeholder: "Inserisci il nome del tuo camp",
                  normal: "Normale",
                  hell: "Hell",
                  queen: "Queen",
                  arakahan: "Arakahan",
                  karkanis: "Karkanis",
                  vera: "Vera",
                  juleeve: "Juleeve",
                  error_no_name_provided: "Nome richiesto!",
                  error_name_in_use: "Stai già utilizzando questo nome!",
                  saved_message: "salvato con successo!",
                  deleted_message: "eliminato!",

                  impostazioni: "Impostazioni",
                  my_teams: "Le mie squadre",
                  most_saved_teams: "Squadre più popolari",
                  refresh_team_stats: "Aggiorna",
                  heroes: "Eroi",
                  teams: "Squadre",
                  extras_map: "Miglior percorso",
                  raid: "RAID",
                  nixied: "Nixied",
                  nixiedinfo: "Nixied's maps by game8. They have a full guide here: ",

                  //Right click menu
                  view_on_e7db: "Visualizza dettagli eroe su EpicSevenDB.com",
                  view_hero_model: "Visualizza modello 2D su e7herder.com",
                  calculate_highest_friendship: "Calcola miglior friendship combo",
                  skills_not_enhanced: "Skills are awakened but not enhanced",
                  e7api_missing_character: "Questo eroe non è presente nel database di EpicSevenDB",
                  e7api_couldnt_connect: "Impossibile connettersi a EpicSevenDB",

                  tema_notturno: "Tema notturno",
                  vert_iconbar: "Toolbar verticale",
                  notifiche: "Notifiche",
                  debug_camping_values: "Debug: Mostra i valori delle opzioni",
                  hero_name_under_pic_grid: "Mostra il nome eroe sotto l'immagine",
                  genera_url: "Genera URL",
                  url_usage_help: "Copia e incolla questo URL nel browser o dispositivo desiderato per generare una copia dei tuoi eroi attuali.",
                  customize_ch_icons: "Personalizza icone",
                  small: "Piccola",
                  default: "Predefinita",
                  medium: "Media",
                  large: "Grande",
                  settings_samll_help: "Puoi cambiare le preferenze ogni volta che vuoi nella finestra impostazioni",
                  attr_role: "Elemento e classe",
                  stars: "Stelle (Rango)",
                  enable_mouseover_zoom: "Ingrandisci al passaggio del mouse (solo su PC)",
                  copia: "Copia",
                  save: "Salva",
                  confirm: "Conferma",
                  selected: "Selezionati",
                  canc_btn: "Annulla",
                  back_btn: "Indietro",
                  others: "Altri",
                  language: "Lingua"
                };
              } else if (this.lingua == "cn") {
                this.strings = {
                  welcome: "欢迎",
                  whats_new: "更新日志",
                  instructions: "简明教程",
                  websites: "实用链接",
                  credits: "作者",
                  messaggio_di_benvenuto: "欢迎使用第七史诗露营模拟器",
                  data_by: "数据来源 EpicSevenDB",
                  all: "全部",
                  sort: "排序",
                  filter: "筛选",
                  modified: "添加日期",
                  name: "英雄名称",
                  ingame_id: "英雄ID",
                  remove_displayed_heroes: "移除下方显示的英雄",
                  add_displayed_heroes: "添加下方显示的英雄",
                  confirm_remove_heroes: "你确定要从你的英雄列表里删除以下 <N> 个英雄?", // <N> is replaced by the number of heroes
                  confirm_add_heroes: "你确定要往你的英雄列表里添加以下 <N> 个英雄?", // <N> is replaced by the number of heroes
                  aggiungi: "添加英雄 ",
                  i_tuoi_eroi: "我的英雄",
                  cant_lock_more_heroes: "不能锁定超过4个英雄",
                  search: "搜索",
                  impostazioni_avanzate: "高级设置",
                  warn_tsize_adv_title: "你有大量的英雄并且没有锁定任何英雄，计算可能耗费较长时间",
                  warn_tsize_adv_details: "使用高级设定会耗费更多时间计算. \n你可以通过锁定英雄来提高计算速度.",
                  numero_massimo_risultati: "显示结果数量 (MAX 10.000)",
                  morale_minimo_risultati: "最低心情限制",
                  includi_locked_in_adv: "高级设置包括锁定的英雄",
                  adv_mute_locked_heroes: "排除对话里包含锁定英雄的队伍",
                  disabilita_immagini_in_risultati: "结果页不显示英雄头像 (如果你设定的显示结果数量非常大，关闭英雄头像显示有助于提升性能)",
                  deve_contenere_AoE: "队伍必须包含 AoE",
                  no_s1_debuffs: "S1不带Debuff (挑衅, 睡眠, 晕眩 和中毒除外)",
                  no_debuffs: "技能不带Debuff (挑衅, 睡眠, 晕眩 和中毒除外)",
                  must_include_dispel: "队伍必须包含驱散角色",
                  must_include_cleanser: "队伍必须包含净化角色 (消除队友身上的debuff或者减少其回合数)",
                  classe: "职业",
                  attribute: "属性",
                  rarity: "稀有度",
                  knight: "骑士",
                  warrior: "战士",
                  thief: "盗贼",
                  ranger: "射手",
                  mage: "魔导士",
                  "soul-weaver": "精灵师",
                  fire: "火焰属性",
                  ice: "寒气属性",
                  earth: "自然属性",
                  light: "光明属性",
                  dark: "黑暗属性",
                  elemento: "属性",
                  buff: "Buff",
                  debuff: "Debuff",
                  combinations: "可能的组合",
                  multilock: "锁定多人 (笛卡尔乘积)",
                  multilock_slot: "栏位",
                  add_to_slot: "添加到这个位置",
                  add_selection: "添加",
                  seleziona: "选择",
                  deselect_all : "全部取消选中",
                  possibili_combinazioni: "可能的组合:",

                  //Help window
                  add_heroes_help: "点击英雄头像将英雄添加到你的英雄列表.<br>\
                            你的英雄列表里的所有英雄将会用于计算可能的排列组合并给出心情最高的前200个结果.<br>\
                            可添加的英雄没有数量限制，添加英雄越多计算越慢.<br>\
                            你的英雄将会自动保存，不需要每次打开页面都重新选择，但是清除页面Cookie将会丢失你保存的设置和英雄列表!<br>\
                            如果你使用的是\"列表\"视图(可在搜索框右方切换) 点击\"+\" 号添加英雄至你的英雄列表<br>",
                  manage_heroes:"英雄列表管理",
                  manage_heroes_help:"在这个界面你可以查看所有保存的英雄.<br>\
                            点击英雄头像上的 \"x\" 就可以删除英雄.<br>\
                            点击英雄头像可以锁定英雄，被锁定的英雄将会出现在所有的计算结果中.<br>\
                            你可以点击工具栏的篝火图标计算露营心情，或者点击记事本图标添加高级选项.<br>", 
                  calculate_highest_friendship_help: "计算包含这个英雄的最高心情组合;<br>\
                            队伍心情将不会计算, 取而代之的是角色心情.<br>\
                            高级设定将会被忽略, 确保你的英雄列表里至少有4个英雄!",
                  advanced_settings_help:"这里可以进行高级设置.<br>\
                            <b style=\"color:red\">被锁定的英雄不受高级设置影响</b><br><br>\
                            你可以选择任意数量的选项，但是某些选项有特殊的限制.<br>\
                            例如你在职业一栏勾选超过4个职业就会报错，因为一个队伍最多不超过4个人.<br>\
                            因为被锁定的英雄无视高级设置限制，所以如果你锁定了 \"塔瑪林爾(偶像)\" 然后在高级设置的职业一栏选中了精灵师，那么在计算结果中 除了偶像还会再添加一个精灵师. 对于Buff和Debuff也是同理<br>",
                  multilock_help:"每个栏位代表队伍里的一个位置, 每个栏位可以添加任意数量的英雄.<br>\
                            计算结果中的每一个位置，只会出现对应栏位中的英雄. 同一个英雄不能被添加到多个栏位中.<br>\
                            空白的栏位对应你的英雄列表中剩余的全部英雄.<br>\
                            如果你将所有的英雄加到前三个栏位中将会出现 \"所有英雄添加完毕，已无英雄可添加至下一个栏位!\" 的错误信息.<br>\
                            空白的栏位将会受到高级设置的影响.<br><br>\
                            每个栏位中被锁定的英雄将无视高级设置的影响.<br>\
                            如果你所有栏位都放入了英雄，同时又选择了任意一个高级设置， 将会报错 \"队伍人数超过上限!\" 并返回 0 个计算结果.<br>\
                            这个选项有助于创建自定义队伍, 比如你将你所有的骑士放在一个栏位中，那么你所有的计算结果里就必定会出现一个骑士!<br>",
                  results_help : "这里会出现根据你的设置筛选出的心情最高的前200个结果.<br>\
                             你的英雄列表里至少要有4个英雄才能显示结果.<br>\
                             你可以点击每个结果前面的图标保存对应的队伍 (会弹出一个窗口要求你自定义队伍名称), 你保存的队伍会出现在右下方齿轮图标的\"设置\"一栏里.<br>",

                  //Results window
                  risultati: "计算结果",
                  morale: "心情",
                  team: "队伍",
                  topics: "对话",
                  abort_calculation: "中止计算",
                  confirm_worker_termination: "您确定要中止这次计算?",
                  notification_title: "E7 露营模拟器",
                  notification_ready: "结果计算完毕!",
                  results_error: "错误",
                  team_size_exceeded: "队伍人数超过上限!",
                  not_enough_heroes: "所有英雄添加完毕，已无英雄可添加至下一个栏位!",
                  locked_sc_normal_err: "转职英雄和转职前英雄不能同时出现在一个队伍!",

                  ///Result saving window:
                  camp_name_field: "队伍名称",
                  camp_name_placeholder: "你的队伍名称",
                  normal: "普通",
                  hell: "地狱",
                  queen: "阿吉曼夏洛斯女王",
                  arakahan: "捕食者阿拉哈坎",
                  karkanis: "执行者卡尔卡努斯",
                  vera: "侍从官培拉",
                  juleeve: "乔里夫议会",
                  error_no_name_provided: "队伍名称不能为空!",
                  error_name_in_use: "该名称已经被使用!",
                  saved_message: "保存成功!",
                  deleted_message: "删除成功!",

                  impostazioni: "设置",
                  my_teams: "我的队伍",
                  most_saved_teams: "常用队伍&英雄",
                  refresh_team_stats: "刷新",
                  heroes: "英雄",
                  teams: "队伍",
                  extras_map: "迷宫最佳路线",
                  raid: "逆袭迷宫",
                  nixied: "尼克斯特的圣所",
                  nixiedinfo: "尼克斯特的圣所地图 by game8. 点击查看详细说明: ",

                  //Right click menu
                  view_on_e7db: " 前往EpicSevenDB.com查看英雄详细信息",
                  view_hero_model: "前往e7herder.com查看英雄模型",
                  calculate_highest_friendship: "计算当前英雄最高心情",
                  skills_not_enhanced: "技能已经觉醒但是并没有强化",
                  e7api_missing_character: "在 EpicSevenDB 暂时找不到该英雄的信息",
                  e7api_couldnt_connect: "无法连接到 EpicSevenDB",

                  tema_notturno: "夜间模式",
                  vert_iconbar: "垂直工具栏",
                  notifiche: "启用通知",
                  debug_camping_values: "调试: 显示所有对话心情值",
                  hero_name_under_pic_grid: "在英雄头像下方显示英雄名字",
                  genera_url: "生成URL链接",
                  url_usage_help: "复制这个链接到新设备来导入你的英雄列表. <br>设备间并不会自动同步, 如果你修改了英雄列表，下次导入前需要重新生成URL链接.",
                  customize_ch_icons: "自定义英雄头像",
                  small: "小",
                  default: "默认",
                  medium: "中",
                  large: "大",
                  settings_samll_help: "你可以随时在设置界面里更改这个设定!",
                  attr_role: "属性和职业",
                  stars: "星级",
                  enable_mouseover_zoom: "鼠标悬停时放大头像 (仅适用于PC)",
                  copia: "复制",
                  save: "保存",
                  confirm: "确认",
                  canc_btn: "取消",
                  back_btn: "返回",
                  selected: "已选择",
                  others: "其它",
                  language: "语言"
                };
              } else if (this.lingua == "zht") {
                this.strings = {
                  welcome: "歡迎",
                  whats_new: "更新日誌",
                  instructions: "簡明教程",
                  websites: "實用鏈接",
                  credits: "作者",
                  messaggio_di_benvenuto: "歡迎使用第七史詩露營模擬器",
                  data_by: "數據來源 EpicSevenDB",
                  all: "全部",
                  sort: "排序",
                  filter: "篩選",
                  modified: "添加日期",
                  name: "英雄名稱",
                  ingame_id: "英雄ID",
                  remove_displayed_heroes: "移除下方顯示的英雄",
                  add_displayed_heroes: "添加下方顯示的英雄",
                  confirm_remove_heroes: "你確定要從你的英雄列表裏刪除以下 <N> 個英雄?", // <N> is replaced by the number of heroes
                  confirm_add_heroes: "你確定要往你的英雄列表裏添加以下 <N> 個英雄?", // <N> is replaced by the number of heroes
                  aggiungi: "添加英雄 ",
                  i_tuoi_eroi: "我的英雄",
                  cant_lock_more_heroes: "不能鎖定超過4個英雄！",
                  search: "搜索",
                  impostazioni_avanzate: "高級設定",
                  warn_tsize_adv_title: "你有大量的英雄並且冇有鎖定任何英雄，計算可能耗費較長時間",
                  warn_tsize_adv_details: "使用高級設定會耗費更多時間計算. \n你可以通過鎖定英雄來提高計算速度.",
                  numero_massimo_risultati: "顯示結果數量 (MAX 10.000)",
                  morale_minimo_risultati: "最低心情限制",
                  includi_locked_in_adv: "高級設置包括鎖定的英雄",
                  adv_mute_locked_heroes: "排除對話裏包含鎖定英雄的隊伍",
                  disabilita_immagini_in_risultati: "結果頁不顯示英雄頭像 (如果你設定的顯示結果數量非常大，關閉英雄頭像顯示有助於提升性能)",
                  deve_contenere_AoE: "隊伍必須包含 AoE",
                  no_s1_debuffs: "S1不帶Debuff (挑釁, 睡眠，暈眩 和中毒除外)",
                  no_debuffs: "技能不帶Debuff (挑釁, 睡眠，暈眩 和中毒除外)",
                  must_include_dispel: "隊伍必須包含驅散角色",
                  must_include_cleanser: "隊伍必須包含淨化角色 (消除隊友身上的debuff或者減少其回合數)",
                  classe: "職階",
                  attribute: "屬性",
                  rarity: "稀有度",
                  knight: "騎士",
                  warrior: "戰士",
                  thief: "盜賊",
                  ranger: "射手",
                  mage: "魔導士",
                  "soul-weaver": "精靈師",
                  fire: "火焰屬性",
                  ice: "寒氣屬性",
                  earth: "自然屬性",
                  light: "光明屬性",
                  dark: "黑暗屬性",
                  elemento: "屬性",
                  buff: "Buff",
                  debuff: "Debuff",
                  combinations: "可能的組合",
                  multilock: "鎖定多人 (笛卡兒積)",
                  multilock_slot: "欄位",
                  add_to_slot: "添加到這個位置",
                  add_selection: "添加",
                  seleziona: "選擇",
                  deselect_all : "全部取消選中",
                  possibili_combinazioni: "可能的組合:",
                  
                  //Help window
                  add_heroes_help: "點選英雄頭像將英雄添加到你的英雄列表.<br>\
                            你的英雄列表裏的所有英雄將會用於計算可能的排列組合並給出心情最高的前200個結果.<br>\
                            可添加的英雄冇有數量限製，添加英雄越多計算越慢.<br>\
                            你的英雄將會自動保存，不需要每次打開頁麵都重新選擇，但是清除頁麵Cookie將會丟失你保存的設定和英雄列表!<br>\
                            如果你使用的是\"列表\"視圖(可在搜索框右方切換) 點選\"+\" 號添加英雄至你的英雄列表<br>",
                  manage_heroes:"英雄列表管理",
                  manage_heroes_help:"在這個界麵你可以檢視所有保存的英雄.<br>\
                            點選英雄頭像上的 \"x\" 就可以刪除英雄.<br>\
                            點選英雄頭像可以鎖定英雄，被鎖定的英雄將會出現在所有的計算結果中.<br>\
                            你可以點選工具欄的篝火圖示計算露營心情，或者點選記事本圖示添加高級選項.<br>",
                  calculate_highest_friendship_help: "計算包含這個英雄的最高心情組合;<br>\
                            隊伍心情將不會計算, 取而代之的是角色心情.<br>\
                            高級設定將會被忽略, 確保你的英雄列表裏至少有4個英雄!",
                  advanced_settings_help:"這裏可以進行高級設定.<br>\
                            <b style=\"color:red\">被鎖定的英雄不受高級設定影響</b><br><br>\
                            你可以選擇任意數量的選項，但是某些選項有特殊的限製.<br>\
                            例如你在職業一欄勾選超過4個職業就會報錯，因為一個隊伍最多不超過4個人.<br>\
                            因為被鎖定的英雄無視高級設定限製，所以如果你鎖定了 \"塔瑪林爾(偶像)\" 然後在高級設定的職業一欄選中了精靈師，那麼在計算結果中 除了偶像還會再添加一個精靈師. 對於Buff和Debuff也是同理<br>",
                  multilock_help:"每個欄位代表隊伍裏的一個位置, 每個欄位可以添加任意數量的英雄.<br>\
                            計算結果中的每一個位置，隻會出現對應欄位中的英雄. 同一個英雄不能被添加到多個欄位中.<br>\
                            空白的欄位對應你的英雄列表中剩餘的全部英雄.<br>\
                            如果你將所有的英雄加到前三個欄位中將會出現 \"所有英雄添加完畢，已無英雄可添加至下一個欄位!\" 的錯誤信息.<br>\
                            空白的欄位將會受到高級設定的影響.<br><br>\
                            每個欄位中被鎖定的英雄將無視高級設定的影響.<br>\
                            如果你所有欄位都放入了英雄，同時又選擇了任意一個高級設定， 將會報錯 \"隊伍人數超過上限!\" 並返回 0 個計算結果.<br>\
                            這個選項有助於創建自定義隊伍, 比如你將你所有的騎士放在一個欄位中，那麼你所有的計算結果裏就必定會出現一個騎士!<br>",
                  results_help : "這裏會出現根據你的設定篩選出的心情最高的前200個結果.<br>\
                             你的英雄列表裏至少要有4個英雄才能顯示結果.<br>\
                             你可以點選每個結果前麵的圖示保存對應的隊伍 (會彈出一個視窗要求你自定義隊伍名稱), 你保存的隊伍會出現在右下方齒輪圖示的\"設定\"一欄裏.<br>",

                  //Results window
                  risultati: "計算結果",
                  morale: "心情",
                  team: "隊伍",
                  topics: "對話",
                  abort_calculation: "中止計算",
                  confirm_worker_termination: "您確定要中止這次運算?",
                  notification_title: "E7 露營模擬器",
                  notification_ready: "結果計算完畢!",
                  results_error: "錯誤",
                  team_size_exceeded: "隊伍人數超過上限!",
                  not_enough_heroes: "所有英雄添加完畢，已無英雄可添加至下一個欄位!",
                  locked_sc_normal_err: "轉職英雄和轉職前英雄不能同時出現在一個隊伍!",

                  ///Result saving window:
                  camp_name_field: "隊伍名稱",
                  camp_name_placeholder: "你的隊伍名稱",
                  normal: "普通",
                  hell: "地獄",
                  queen: "阿吉曼夏洛斯女王",
                  arakahan: "捕食者阿拉哈坎",
                  karkanis: "執行者卡爾卡努斯",
                  vera: "侍從官培拉",
                  juleeve: "喬裏夫議會",
                  error_no_name_provided: "隊伍名稱不能為空!",
                  error_name_in_use: "該名稱已經被使用!",
                  saved_message: "保存成功!",
                  deleted_message: "刪除成功!",

                  impostazioni: "設定",
                  my_teams: "我的隊伍",
                  most_saved_teams: "常用隊伍&英雄",
                  refresh_team_stats: "刷新",
                  heroes: "英雄",
                  teams: "隊伍",
                  extras_map: "迷宮最佳路線",
                  raid: "逆襲迷宮",
                  nixied: "尼克斯特的聖所",
                  nixiedinfo: "尼克斯特的聖所地圖 by game8. 點選檢視詳細說明: ",

                  //Right click menu
                  view_on_e7db: " 前往EpicSevenDB.com檢視英雄詳細信息",
                  view_hero_model: "前往e7herder.com檢視英雄模型",
                  calculate_highest_friendship: "計算當前英雄最高心情",
                  skills_not_enhanced: "技能已經覺醒但是並未強化",
                  e7api_missing_character: "在 EpicSevenDB 暫時找不到該英雄的信息",
                  e7api_couldnt_connect: "無法連接到 EpicSevenDB",

                  tema_notturno: "夜間模式",
                  vert_iconbar: "垂直工具欄",
                  notifiche: "啟用通知",
                  debug_camping_values: "調試: 顯示所有對話心情值",
                  hero_name_under_pic_grid: "在英雄頭像下方顯示英雄名字",
                  genera_url: "生成URL鏈接",
                  url_usage_help: "復制這個鏈接到新設備來導入你的英雄列表. <br>設備間並不會自動同步, 如果你修改了英雄列表，下次導入前需要重新生成URL鏈接.",
                  customize_ch_icons: "自定義英雄頭像",
                  small: "小",
                  default: "默認",
                  medium: "中",
                  large: "大",
                  settings_samll_help: "你可以隨時在設置界麵裏更改這個設定!",
                  attr_role: "屬性和職業",
                  stars: "星級",
                  enable_mouseover_zoom: "鼠標懸停時放大頭像 (僅適用於PC)",
                  copia: "複製",
                  save: "保存",
                  confirm: "確認",
                  canc_btn: "取消",
                  back_btn: "返回",
                  selected: "已選擇",
                  others: "其它",
                  language: "語言"
                };
              }else if (this.lingua == "fr") {
                this.strings = {
                  welcome: "Bienvenue",
                  whats_new: "Quoi de neuf",
                  instructions: "Instructions",
                  websites: "Sites web",
                  credits: "Crédits",
                  messaggio_di_benvenuto: "Bienvenue à E7 Camp Simulateur",
                  data_by: "Source EpicSevenDB",
                  all: "Tous",
                  sort: "Trier par",
                  filter: "Filtre",
                  modified: "Date",
                  name: "Nom",
                  ingame_id: "ID",
                  remove_displayed_heroes: "Supprimer les héros affichés",
                  add_displayed_heroes: "Ajouter les héros affichés",
                  confirm_remove_heroes: "Voulez-vous vraiment supprimer <N> héros de votre liste?", // <N> is replaced by the number of heroes
                  confirm_add_heroes: "Voulez-vous vraiment ajouter <N> héros dans votre liste?", // <N> is replaced by the number of heroes
                  aggiungi: "Ajouter un héro ",
                  i_tuoi_eroi: "Votre héros",
                  cant_lock_more_heroes: "Impossible de verrouiller plus de 4 héros",
                  search: "Rechercher",
                  impostazioni_avanzate: "Paramètre avancé",
                  warn_tsize_adv_title: "Vous avez une grande liste de héros et aucun héros verrouillé",
                  warn_tsize_adv_details: "L'activation de toutes les fonctionnalités avancées augmentera le temps nécessaire pour calculer toutes les combinaisons. \nVous pouvez réduire le temps requis en verrouillant un héros.",
                  numero_massimo_risultati: "Nombre maximum de résultats de camping (MAX 10.000)",
                  morale_minimo_risultati: "Minimum morale",
                  includi_locked_in_adv: "Héros verrouillés inclus dans les paramètres avancés",
                  adv_mute_locked_heroes: "Discard team if a topic is held by a locked hero",
                  disabilita_immagini_in_risultati: "Désactiver l'avatar du héro dans l'écran des résultats (Améliorer les performances si vous demandez trop de résultats)",
                  deve_contenere_AoE: "L'équipe doit contenir AoE",
                  no_s1_debuffs: "S1 sans Debuff (Sauf: Provoquer, Sommeil, Etourdir et Poison)",
                  no_debuffs: "Non Debuff (Sauf: Provoquer, Sommeil, Etourdir et Poison)",
                  must_include_dispel: "L'équipe doit contenir stripper",
                  must_include_cleanser: "Team must include cleanser (remove or reduce the duration of debuffs on your allies)",
                  classe: "Classe",
                  attribute: "Attribut",
                  rarity: "Rareté",
                  elemento: "Elément",
                  buff: "Buff",
                  debuff: "Debuff",
                  combinations: "Combinaisons",
                  multilock: "Verrouillage multi",
                  multilock_slot: "Slot",
                  add_to_slot: "Ajouter dans ce slot",
                  add_selection: "Ajouter",
                  seleziona: "Selection",
                  deselect_all : "Tout déselectionner",
                  possibili_combinazioni: "Combinaisons possibles:",

                  //Help window
                  add_heroes_help: "Tap or click the portrait of a hero to add that hero to your roster.<br>\
                            Heroes in your roster will be used to calculate all possible combinations and return the best 200 combinations.<br>\
                            You can add as many heroes as you wish but the time needed to calculate all possible combinations will also increase.<br>\
                            Your roster will be saved and can be used everytime you visit this page without the need to add each hero everytime!<br>\
                            <br>\
                            If you are using the \"List\" display mode tap the \"+\" symbol to add a hero to your roster",
                  manage_heroes:"Manage Heroes",
                  manage_heroes_help:"In this window you can view all the heroes currently in your roster.<br>\
                            You can remove a hero by clicking the \"x\" at the bottom of the hero's portrait.<br>\
                            You can lock a hero by clicking he's portrait, a lock symbol will appear near the portrait. A locked hero will appear in every team in the results page.<br>\
                            You can calculate all the camping results for the current roster by clicking the bonfire icon in the toolbar or click the book icon to add advance settings.",   
                  calculate_highest_friendship_help: "Calculate all the combinations that give the selected character the highest friendship;<br>\
                            Team morale will not be calculated and the morale displayed in the results window will be replaced by the character's friendship (title is morale but please ignore that).<br>\
                            Advanced settings will be ignored and all the combinations will be generated using your roster, make sure you have at least 4 characters in your roster!",
                  advanced_settings_help:"Here you can costumize your camp results.<br>\
                            <b style=\"color:red\">Locked heroes are not subject to these restrictions</b><br><br>\
                            You can select as many as you want but keep in mind time size while doing so.<br>\
                            For example if you lock 5 classes or 5 elements you will get a team size error.<br>\
                            Because locked heroes ignore advanced settings if you lock \"Tamarinne\" and select Soul weaver as a class you will get \"Tamarinne\" + another Soul weaver in every team. The same thing applies to Buffs and Debuffs<br>",
                  multilock_help:"Each slot is a space in your team, on each slot you can add as many heroes as you wish.<br>\
                            Only one of the Heroes locked for each slot will be in the results. The same hero can't be added on multiple slots.<br>\
                            Empty slots will be filled with the remaining heroes in your roster.<br>\
                            If you use all your heroes to fill 3 or less slots and no heroes are left to fill the remaining slots you will get a \"not enough heroes left\" error.<br>\
                            Slots that are left empty will be subject of restrictions from advanced settings.<br><br>\
                            Locked heroes in one of the slots will ignore advanced settings.<br>\
                            If you fill all the slots and select any advanced settings you will get a \"team size exceeded\" error or 0 results.<br>\
                            This option is useful to create costum rules, for example you can put all your knights in 1 slot and you will get a knight for each team in the results!",
                  results_help : "Here are displayed the best 200 combinations for your roster and current advanced settings.<br>\
                            You need at least 4 heroes in your current roster for any result to be displayed.<br>\
                            You can click the floppy disk icon to save a specific team composition (you will be prompted to input a name for that team), your saved teams will be displayed in the settings window.",

                  //Results window
                  risultati: "Résultat",
                  morale: "Morale",
                  team: "Equipe",
                  topics: "Conversations",
                  abort_calculation: "Annuler l'opération",
                  confirm_worker_termination: "Voulez-vous vraiment annuler cette opération?",
                  notification_title: "E7 Camp Simulateur",
                  notification_ready: "Calcul terminé!",
                  results_error: "Erreur",
                  team_size_exceeded: "Le nombre maximum de héros dans l'équipe dépassé!",
                  not_enough_heroes: "Il n'y aura plus de héro disponible pour la prochaine slot!",
                  locked_sc_normal_err: "SC héro et non SC version sont verrouillés en même temps!",

                  ///Result saving window:
                  camp_name_field: "Nom",
                  camp_name_placeholder: "Nom de votre equipe",
                  normal: "Normal",
                  hell: "Hell",
                  queen: "La Reine",
                  arakahan: "Arakahan",
                  karkanis: "Karkanis",
                  vera: "Vera",
                  juleeve: "Juleeve",
                  error_no_name_provided: "Le nom ne peut pas être vide!",
                  error_name_in_use: "Ce nom est déjà pris!",
                  saved_message: "Sauvgardée!",
                  deleted_message: "Supprimée!",

                  impostazioni: "Paramètres",
                  my_teams: "Mes équipes",
                  most_saved_teams: "Équipes & Héros les plus utilisés",
                  refresh_team_stats: "Rafraîchir",
                  heroes: "Héros",
                  teams: "Équipes",
                  extras_map: "Meilleur itinéraire pour Raid hell",
                  raid: "RAID",
                  nixied: "Nixied",
                  nixiedinfo: "Carte Nixied par game8. Lire le guide complet ici: ",

                  //Right click menu
                  view_on_e7db: "Voir les détails du héro sur EpicSevenDB.com",
                  view_hero_model: "Voir le modèle de héro sur e7herder.com",
                  calculate_highest_friendship: "Calculate Friendship Farming",
                  skills_not_enhanced: "Les compétences sont éveillées mais pas améliorées",
                  e7api_missing_character: "Impossible de trouver ce héro sur EpicSevenDB",
                  e7api_couldnt_connect: "Impossible de se connecter à EpicSevenDB",

                  tema_notturno: "Mode nuit",
                  vert_iconbar: "Barre d'outils verticale",
                  notifiche: "Notification",
                  debug_camping_values: "Debug: Afficher tous les valeurs de conversation",
                  hero_name_under_pic_grid: "Afficher le nom du héros sous le portrait",
                  genera_url: "Générer une URL",
                  url_usage_help: "Copiez et collez cette URL sur un nouvel appareil ou navigateur pour générer une copie de votre liste de héros actuelle. <br>Les modifications ne sont pas synchronisées, si vous changez votre liste, vous devrez générer une nouvelle URL.",
                  customize_ch_icons: "Personnaliser les icônes",
                  small: "Petit",
                  default: "Par défaut",
                  medium: "Moyen",
                  large: "Grand",
                  settings_samll_help: "Si vous le souhaitez, vous pouvez modifier vos paramètres à tout moment dans l'onglet Paramètres!",
                  attr_role: "Attribut et rôle",
                  stars: "Etoiles",
                  enable_mouseover_zoom: "Faites passer la souris pour faire un zoom (PC uniquement)",
                  copia: "Copier",
                  save: "Sauvgarde",
                  confirm: "Confirmer",
                  canc_btn: "Annuler",
                  back_btn: "Retour",
                  selected: "Sélectionné",
                  others: "Autres",
                  language: "Langue"
                };
              } else {
                //this.lingua = "en";
                this.strings = {
                  welcome: "Welcome",
                  whats_new: "What's new",
                  instructions: "Instructions",
                  websites: "Websites",
                  credits: "Credits",
                  messaggio_di_benvenuto: "Welcome to Epic Seven Camp simulator",
                  data_by: "Data by EpicSevenDB",
                  all: "All",
                  sort: "Sort by",
                  filter: "Filter",
                  modified: "Date",
                  name: "Name",
                  ingame_id: "In-game ID",
                  remove_displayed_heroes: "Remove displayed heroes",
                  add_displayed_heroes: "Add displayed heroes",
                  confirm_remove_heroes: "Are you sure you want to remove <N> heroes from your roster?", // <N> is replaced by the number of heroes
                  confirm_add_heroes: "Are you sure you want to add <N> heroes to your roster?", // <N> is replaced by the number of heroes
                  aggiungi: "Add hero ",
                  i_tuoi_eroi: "Your heroes",
                  cant_lock_more_heroes: "Can't lock more than 4 heroes",
                  search: "Search",
                  impostazioni_avanzate: "Advanced settings",
                  warn_tsize_adv_title: "You have a large roster and no heroes locked",
                  warn_tsize_adv_details: "Activating any advanced features will increse the required time to calculate all the combinations. \nYou can reduce the required time by locking a hero.",
                  numero_massimo_risultati: "Maximum number of camping results (MAX 10.000)",
                  morale_minimo_risultati: "Minimum morale",
                  includi_locked_in_adv: "Locked heroes count towards the fulfillment of the selected advanced settings",
                  adv_mute_locked_heroes: "Discard team if a topic is held by a locked hero",
                  disabilita_immagini_in_risultati: "Disable character's avatar in results screen (better performance for your browser if you request too many results)",
                  deve_contenere_AoE: "Team must have AoE",
                  no_s1_debuffs: "No S1 Debuffs (Except: Provoke, Sleep, Stun and Poison)",
                  no_debuffs: "No Debuffs (Except: Provoke, Sleep, Stun and Poison)",
                  must_include_dispel: "Team must include dispel (remove enemy's buffs or reduce their duration)",
                  must_include_cleanser: "Team must include cleanser (remove or reduce the duration of debuffs on your allies)",
                  classe: "Class",
                  attribute: "Attribute",
                  rarity: "Rarity",
                  knight: "Knight",
                  warrior: "Warrior",
                  thief: "Thief",
                  ranger: "Ranger",
                  mage: "Mage",
                  "soul-weaver": "Soul Weaver",
                  fire: "Fire",
                  ice: "Ice",
                  earth: "Earth",
                  light: "Light",
                  dark: "Dark",
                  elemento: "Element",
                  buff: "Buff",
                  debuff: "Debuff",
                  combinations: "Possible combinations",
                  multilock: "Multi-lock (Cartesian Product)",
                  multilock_slot: "Slot",
                  add_to_slot: "Add to this slot",
                  seleziona: "Select",
                  deselect_all : "Deselect all",
                  add_selection: "Add selection",
                  possibili_combinazioni: "Combinations:",
                  
                  //Help window
                  add_heroes_help: "Tap or click the portrait of a hero to add that hero to your roster.<br>\
                            Heroes in your roster will be used to calculate all possible combinations and return the best 200 combinations.<br>\
                            You can add as many heroes as you wish but the time needed to calculate all possible combinations will also increase.<br>\
                            Your roster will be saved and can be used everytime you visit this page without the need to add each hero everytime!<br>\
                            <br>\
                            If you are using the \"List\" display mode tap the \"+\" symbol to add a hero to your roster",
                  manage_heroes:"Manage Heroes",
                  manage_heroes_help:"In this window you can view all the heroes currently in your roster.<br>\
                            You can remove a hero by clicking the \"x\" at the bottom of the hero's portrait.<br>\
                            You can lock a hero by clicking he's portrait, a lock symbol will appear near the portrait. A locked hero will appear in every team in the results page.<br>\
                            You can calculate all the camping results for the current roster by clicking the bonfire icon in the toolbar or click the book icon to add advance settings.",
                  calculate_highest_friendship_help: "Calculate all the combinations that give the selected character the highest friendship;<br>\
                            Team morale will not be calculated and the morale displayed in the results window will be replaced by the character's friendship (title is morale but please ignore that).<br>\
                            Advanced settings will be ignored and all the combinations will be generated using your roster, make sure you have at least 4 characters in your roster!",
                  advanced_settings_help:"Here you can costumize your camp results.<br>\
                            <b style=\"color:red\">Locked heroes are not subject to these restrictions</b><br><br>\
                            You can select as many as you want but keep in mind time size while doing so.<br>\
                            For example if you lock 5 classes or 5 elements you will get a team size error.<br>\
                            Because locked heroes ignore advanced settings if you lock \"Tamarinne\" and select Soul weaver as a class you will get \"Tamarinne\" + another Soul weaver in every team. The same thing applies to Buffs and Debuffs<br>",
                  multilock_help:"Each slot is a space in your team, on each slot you can add as many heroes as you wish.<br>\
                            Only one of the Heroes locked for each slot will be in the results. The same hero can't be added on multiple slots.<br>\
                            Empty slots will be filled with the remaining heroes in your roster.<br>\
                            If you use all your heroes to fill 3 or less slots and no heroes are left to fill the remaining slots you will get a \"not enough heroes left\" error.<br>\
                            Slots that are left empty will be subject of restrictions from advanced settings.<br><br>\
                            Locked heroes in one of the slots will ignore advanced settings.<br>\
                            If you fill all the slots and select any advanced settings you will get a \"team size exceeded\" error or 0 results.<br>\
                            This option is useful to create costum rules, for example you can put all your knights in 1 slot and you will get a knight for each team in the results!",
                  results_help : "Here are displayed the best 200 combinations for your roster and current advanced settings.<br>\
                            You need at least 4 heroes in your current roster for any result to be displayed.<br>\
                            You can click the floppy disk icon to save a specific team composition (you will be prompted to input a name for that team), your saved teams will be displayed in the settings window.",

                  //Results window
                  risultati: "Results",
                  morale: "Morale",
                  team: "Team",
                  topics: "Topics",
                  abort_calculation: "Abort operation",
                  confirm_worker_termination: "Are you sure you want to abort this operation?",
                  notification_title: "E7 Camp Simulator",
                  notification_ready: "Your results are ready!",
                  results_error: "Error",
                  team_size_exceeded: "Team size exceeded!",
                  not_enough_heroes: "No heroes to fill the remaining slots!",
                  locked_sc_normal_err: "Both SC and normal hero are locked",

                  ///Result saving window:
                  camp_name_field: "Camp name",
                  camp_name_placeholder: "Your camp's name",
                  normal: "Normal",
                  hell: "Hell",
                  queen: "Queen",
                  arakahan: "Arakahan",
                  karkanis: "Karkanis",
                  vera: "Vera",
                  juleeve: "Juleeve",
                  error_no_name_provided: "Name is required!",
                  error_name_in_use: "You are already using this name!",
                  saved_message: "saved successfully!",
                  deleted_message: "deleted!",

                  impostazioni: "Settings",
                  my_teams: "My teams",
                  most_saved_teams: "Most common teams",
                  refresh_team_stats: "Refresh",
                  heroes: "Heroes",
                  teams: "Teams",
                  extras_map: "Best hell raid route",
                  raid: "RAID",
                  nixied: "Nixied",
                  nixiedinfo: "Nixied's maps by game8. They have a full guide here: ",

                  //Right click menu
                  view_on_e7db: "View hero details on EpicSevenDB.com",
                  view_hero_model: "View hero model on e7herder.com",
                  calculate_highest_friendship: "Calculate Friendship Farming",
                  skills_not_enhanced: "Skills are awakened but not enhanced",
                  e7api_missing_character: "Couldn't find this character on EpicSevenDB",
                  e7api_couldnt_connect: "Couldn't connect to EpicSevenDB",

                  tema_notturno: "Night theme",
                  vert_iconbar: "Vertical toolbar",
                  notifiche: "Enable notifications",
                  debug_camping_values: "Debug: Display camping values",
                  hero_name_under_pic_grid: "Hero's name under the portrait",
                  genera_url: "Generate URL",
                  url_usage_help: "Copy and paste this URL to a new device or browser to generate a copy of your current roster. <br>Changes are not synchronized, if you change your roster you will have to generate a new URL.",
                  customize_ch_icons: "Customize character icons",
                  small: "Small",
                  default: "Default",
                  medium: "Medium",
                  large: "Large",
                  settings_samll_help: "If you wish, you can change your settings at any time in the settings tab!",
                  attr_role: "Attribute and Role",
                  stars: "Stars",
                  enable_mouseover_zoom: "Zoom on mouse over (PC only)",
                  copia: "Copy",
                  save: "Save",
                  confirm: "Confirm",
                  canc_btn: "Cancel",
                  back_btn: "Back",
                  selected: "Selected",
                  others: "Others",
                  language: "Language"
                };
              };


              if (this.lingua == "fr") {
                this.buffList["stic_debuf_impossible"].name = "Immunité";
                this.buffList["stic_att_up"].name = "Attaque augmentée";
                this.buffList["stic_att_up2"].name = "Attaque augmentée (sup.)";
                this.buffList["stic_def_up"].name = "Augmentation de défense";
                this.buffList["stic_speed_up"].name = "Vitesse augmentée";
                this.buffList["stic_dodge_up"].name = "Esquive augmentée";
                this.buffList["stic_protect"].name = "Barrière";
                this.buffList["stic_cri_up"].name = "Augm. Chances Coup Crit.";
                this.buffList["stic_cridmg_up"].name = "Augm. Dégâts Coup Crit.";
                this.buffList["stic_crires_up"].name = "Résistance Coups Critiques";
                this.buffList["stic_invincible"].name = "Invincibilité";
                this.buffList["stic_endure"].name = "Annulateur de compétence";
                this.buffList["stic_heal"].name = "Soin continu";
                this.buffList["stic_hide"].name = "Furtivité";
                this.buffList["stic_immortality"].name = "Immortalité";
                this.buffList["stic_reflect"].name = "Réflexion";
                this.buffList["stic_counter"].name = "Contre-attaque";

                this.debuffList["stic_def_dn"].name = "Réduction de la défense";
                this.debuffList["stic_speed_dn"].name = "Vitesse réduite";
                this.debuffList["stic_att_dn"].name = "Réduction de l'attaque";
                this.debuffList["stic_blind"].name = "Réduc. Chances Coup réussi";
                this.debuffList["stic_target"].name = "Cible";
                this.debuffList["stic_buf_impossible"].name = "Bonus impossible";
                this.debuffList["stic_heal_impossible"].name = "Inguérissable";
                this.debuffList["stic_stun"].name = "Étourdissement";
                this.debuffList["stic_provoke"].name = "Provocation";
                this.debuffList["stic_silence"].name = "Silence";
                this.debuffList["stic_sleep"].name = "Sommeil";
                this.debuffList["stic_blood"].name = "Hémorragie";
                this.debuffList["stic_dot"].name = "Poison";
                this.debuffList["stic_blaze"].name = "Brûlure";
                this.debuffList["stic_vampire"].name = "Toucher vampirique";
                this.debuffList["stic_bomb"].name = "Bombe";

                this.strings["knight"] = "Chevalier";
                this.strings["warrior"] = "Guerrier";
                this.strings["thief"] = "Assassin";
                this.strings["ranger"] = "Tireur";
                this.strings["mage"] = "Mage";
                this.strings["soul-weaver"] = "Tisseur d'âme";
                this.strings["fire"] = "Feu";
                this.strings["ice"] = "Glace";
                this.strings["earth"] = "Terre";
                this.strings["light"] = "Lumière";
                this.strings["dark"] = "Ténèbres";
              } else if (this.lingua == "jp") {
                this.buffList["stic_debuf_impossible"].name = "弱体効果免疫";
                this.buffList["stic_att_up"].name = "攻撃力UP";
                this.buffList["stic_att_up2"].name = "攻撃力UP(大)";
                this.buffList["stic_def_up"].name = "防御力UP";
                this.buffList["stic_speed_up"].name = "スピードUP";
                this.buffList["stic_dodge_up"].name = "回避率UP";
                this.buffList["stic_protect"].name = "シールド";
                this.buffList["stic_cri_up"].name = "クリティカル発生率UP";
                this.buffList["stic_cridmg_up"].name = "クリティカルダメージUP";
                this.buffList["stic_crires_up"].name = "クリティカル抵抗率UP";
                this.buffList["stic_invincible"].name = "無敵";
                this.buffList["stic_endure"].name = "スキルダメージ無効";
                this.buffList["stic_heal"].name = "持続回復";
                this.buffList["stic_hide"].name = "潜伏";
                this.buffList["stic_immortality"].name = "不死";
                this.buffList["stic_reflect"].name = "反射";
                this.buffList["stic_counter"].name = "反撃";

                this.debuffList["stic_def_dn"].name = "防御力DOWN";
                this.debuffList["stic_speed_dn"].name = "スピードDOWN";
                this.debuffList["stic_att_dn"].name = "攻撃力DOWN";
                this.debuffList["stic_blind"].name = "命中率DOWN";
                this.debuffList["stic_target"].name = "標的";
                this.debuffList["stic_buf_impossible"].name = "強化不可";
                this.debuffList["stic_heal_impossible"].name = "回復不可";
                this.debuffList["stic_stun"].name = "スタン";
                this.debuffList["stic_provoke"].name = "挑発";
                this.debuffList["stic_silence"].name = "沈黙";
                this.debuffList["stic_sleep"].name = "睡眠";
                this.debuffList["stic_blood"].name = "出血";
                this.debuffList["stic_dot"].name = "毒";
                this.debuffList["stic_blaze"].name = "火傷";
                this.debuffList["stic_vampire"].name = "吸血";
                this.debuffList["stic_bomb"].name = "爆弾";

                this.strings["knight"] = "ナイト";
                this.strings["warrior"] = "ウォリアー";
                this.strings["thief"] = "アサシン";
                this.strings["ranger"] = "アーチャー";
                this.strings["mage"] = "メイジ";
                this.strings["soul-weaver"] = "プリースト";
                this.strings["fire"] = "火属性";
                this.strings["ice"] = "氷属性";
                this.strings["earth"] = "木属性";
                this.strings["light"] = "光属性";
                this.strings["dark"] = "闇属性";
              } else if (this.lingua == "kr") {
                this.buffList["stic_debuf_impossible"].name = "면역";
                this.buffList["stic_att_up"].name = "공격력 증가";
                this.buffList["stic_att_up2"].name = "공격력 증가 (대)";
                this.buffList["stic_def_up"].name = "방어력 증가";
                this.buffList["stic_speed_up"].name = "속도 증가";
                this.buffList["stic_dodge_up"].name = "회피 증가";
                this.buffList["stic_protect"].name = "보호막";
                this.buffList["stic_cri_up"].name = "치명확률 증가";
                this.buffList["stic_cridmg_up"].name = "치명피해 증가";
                this.buffList["stic_crires_up"].name = "치명저항 증가";
                this.buffList["stic_invincible"].name = "무적";
                this.buffList["stic_endure"].name = "스킬 대미지 무효";
                this.buffList["stic_heal"].name = "지속 회복";
                this.buffList["stic_hide"].name = "은신";
                this.buffList["stic_immortality"].name = "불사";
                this.buffList["stic_reflect"].name = "반사";
                this.buffList["stic_counter"].name = "반격";

                this.debuffList["stic_def_dn"].name = "방어력 감소";
                this.debuffList["stic_speed_dn"].name = "속도 감소";
                this.debuffList["stic_att_dn"].name = "공격력 감소";
                this.debuffList["stic_blind"].name = "명중 감소";
                this.debuffList["stic_target"].name = "표적";
                this.debuffList["stic_buf_impossible"].name = "강화 불가";
                this.debuffList["stic_heal_impossible"].name = "회복 불가";
                this.debuffList["stic_stun"].name = "기절";
                this.debuffList["stic_provoke"].name = "도발";
                this.debuffList["stic_silence"].name = "침묵";
                this.debuffList["stic_sleep"].name = "수면";
                this.debuffList["stic_blood"].name = "출혈";
                this.debuffList["stic_dot"].name = "중독";
                this.debuffList["stic_blaze"].name = "화상";
                this.debuffList["stic_vampire"].name = "흡혈의 손길";
                this.debuffList["stic_bomb"].name = "폭탄";

                this.strings["knight"] = "기사";
                this.strings["warrior"] = "전사";
                this.strings["thief"] = "도적";
                this.strings["ranger"] = "사수";
                this.strings["mage"] = "마도사";
                this.strings["soul-weaver"] = "정령사";
                this.strings["fire"] = "화염속성";
                this.strings["ice"] = "냉기속성";
                this.strings["earth"] = "자연속성";
                this.strings["light"] = "광속성";
                this.strings["dark"] = "암속성";
              } else if (lingua == "cn") {
                this.buffList["stic_debuf_impossible"].name = "免疫";
                this.buffList["stic_att_up"].name = "攻击力增加";
                this.buffList["stic_att_up2"].name = "攻击力大幅增加";
                this.buffList["stic_def_up"].name = "防御力增加";
                this.buffList["stic_speed_up"].name = "速度提升";
                this.buffList["stic_dodge_up"].name = "增加回避";
                this.buffList["stic_protect"].name = "防护罩";
                this.buffList["stic_cri_up"].name = "暴击率增加";
                this.buffList["stic_cridmg_up"].name = "增加暴击伤害";
                this.buffList["stic_crires_up"].name = "暴击抗性增加";
                this.buffList["stic_invincible"].name = "无敌";
                this.buffList["stic_endure"].name = "技能伤害无效";
                this.buffList["stic_heal"].name = "持续恢复";
                this.buffList["stic_hide"].name = "隐身";
                this.buffList["stic_immortality"].name = "不死";
                this.buffList["stic_reflect"].name = "反射";
                this.buffList["stic_counter"].name = "反击";

                this.debuffList["stic_def_dn"].name = "防御力减少";
                this.debuffList["stic_speed_dn"].name = "速度下降";
                this.debuffList["stic_att_dn"].name = "攻击力减少";
                this.debuffList["stic_blind"].name = "命中减少";
                this.debuffList["stic_target"].name = "标靶";
                this.debuffList["stic_buf_impossible"].name = "无法强化";
                this.debuffList["stic_heal_impossible"].name = "无法恢复";
                this.debuffList["stic_stun"].name = "晕眩";
                this.debuffList["stic_provoke"].name = "挑衅";
                this.debuffList["stic_silence"].name = "沉默";
                this.debuffList["stic_sleep"].name = "睡眠";
                this.debuffList["stic_blood"].name = "出血";
                this.debuffList["stic_dot"].name = "中毒";
                this.debuffList["stic_blaze"].name = "烧伤";
                this.debuffList["stic_vampire"].name = "吸血之手";
                this.debuffList["stic_bomb"].name = "炸弹";
              } else if (lingua == "zht") {
                this.buffList["stic_debuf_impossible"].name = "免疫";
                this.buffList["stic_att_up"].name = "攻擊力增加";
                this.buffList["stic_att_up2"].name = "攻擊力大幅增加";
                this.buffList["stic_def_up"].name = "防禦力增加";
                this.buffList["stic_speed_up"].name = "速度提升";
                this.buffList["stic_dodge_up"].name = "增加迴避";
                this.buffList["stic_protect"].name = "防護罩";
                this.buffList["stic_cri_up"].name = "暴擊率增加";
                this.buffList["stic_cridmg_up"].name = "增加暴擊傷害";
                this.buffList["stic_crires_up"].name = "暴擊抗性增加";
                this.buffList["stic_invincible"].name = "無敵";
                this.buffList["stic_endure"].name = "技能傷害無效";
                this.buffList["stic_heal"].name = "持續恢復";
                this.buffList["stic_hide"].name = "隱身";
                this.buffList["stic_immortality"].name = "不死";
                this.buffList["stic_reflect"].name = "反射";
                this.buffList["stic_counter"].name = "反擊";

                this.debuffList["stic_def_dn"].name = "防禦力減少";
                this.debuffList["stic_speed_dn"].name = "速度下降";
                this.debuffList["stic_att_dn"].name = "攻擊力減少";
                this.debuffList["stic_blind"].name = "命中減少";
                this.debuffList["stic_target"].name = "標靶";
                this.debuffList["stic_buf_impossible"].name = "無法強化";
                this.debuffList["stic_heal_impossible"].name = "無法恢復";
                this.debuffList["stic_stun"].name = "暈眩";
                this.debuffList["stic_provoke"].name = "挑釁";
                this.debuffList["stic_silence"].name = "沉默";
                this.debuffList["stic_sleep"].name = "睡眠";
                this.debuffList["stic_blood"].name = "出血";
                this.debuffList["stic_dot"].name = "中毒";
                this.debuffList["stic_blaze"].name = "燒傷";
                this.debuffList["stic_vampire"].name = "吸血之手";
                this.debuffList["stic_bomb"].name = "炸彈";
              } else if (lingua == "th") {
                this.buffList["stic_debuf_impossible"].name = "ภูมิคุ้มกัน";
                this.buffList["stic_att_up"].name = "เพิ่มพลังโจมตี";
                this.buffList["stic_att_up2"].name = "เพิ่มพลังโจมตี (ชั้นสูง)";
                this.buffList["stic_def_up"].name = "เพิ่มพลังป้องกัน";
                this.buffList["stic_speed_up"].name = "เพิ่มความเร็ว";
                this.buffList["stic_dodge_up"].name = "เพิ่มการหลบหลีก";
                this.buffList["stic_protect"].name = "บาเรีย";
                this.buffList["stic_cri_up"].name = "เพิ่มโอกาสคริติคอล";
                this.buffList["stic_cridmg_up"].name = "เพิ่มดาเมจคริติคอล";
                this.buffList["stic_crires_up"].name = "เพิ่มความต้านทานคริติคอล";
                this.buffList["stic_invincible"].name = "คงกระพัน";
                this.buffList["stic_endure"].name = "ล้างดาเมจสกิล";
                this.buffList["stic_heal"].name = "รักษาต่อเนื่อง";
                this.buffList["stic_hide"].name = "ซ่อนตัว";
                this.buffList["stic_immortality"].name = "อมตะ";
                this.buffList["stic_reflect"].name = "สะท้อน";
                this.buffList["stic_counter"].name = "โจมตีโต้กลับ";

                this.debuffList["stic_def_dn"].name = "ลดพลังป้องกัน";
                this.debuffList["stic_speed_dn"].name = "ลดความเร็ว";
                this.debuffList["stic_att_dn"].name = "ลดพลังโจมตี";
                this.debuffList["stic_blind"].name = "ลดความแม่นยำ";
                this.debuffList["stic_target"].name = "ตกเป็นเป้า";
                this.debuffList["stic_buf_impossible"].name = "ห้ามบัฟ";
                this.debuffList["stic_heal_impossible"].name = "ห้ามการฟื้นฟู";
                this.debuffList["stic_stun"].name = "สตัน";
                this.debuffList["stic_provoke"].name = "ยั่วยุ";
                this.debuffList["stic_silence"].name = "เป็นใบ้";
                this.debuffList["stic_sleep"].name = "หลับ";
                this.debuffList["stic_blood"].name = "เลือดไหล";
                this.debuffList["stic_dot"].name = "พิษ";
                this.debuffList["stic_blaze"].name = "เผาไหม้";
                this.debuffList["stic_vampire"].name = "สัมผัสแวมไพร์";
                this.debuffList["stic_bomb"].name = "ระเบิด";
              } else if (lingua == "es") {
                this.buffList["stic_debuf_impossible"].name = "Inmunidad";
                this.buffList["stic_att_up"].name = "Aumenta el ataque";
                this.buffList["stic_att_up2"].name = "Aumenta el ataque (mayor)";
                this.buffList["stic_def_up"].name = "Aumenta la defensa";
                this.buffList["stic_speed_up"].name = "Aumenta la velocidad";
                this.buffList["stic_dodge_up"].name = "Aumenta la evasión";
                this.buffList["stic_protect"].name = "Barrera";
                this.buffList["stic_cri_up"].name = "Aumenta la probabilidad de golpe crítico";
                this.buffList["stic_cridmg_up"].name = "Aumenta el daño de golpe crítico";
                this.buffList["stic_crires_up"].name = "Aumenta la resistencia a golpes críticos";
                this.buffList["stic_invincible"].name = "Invencible";
                this.buffList["stic_endure"].name = "Anulador de habilidades";
                this.buffList["stic_heal"].name = "Curación continua";
                this.buffList["stic_hide"].name = "Sigilo";
                this.buffList["stic_immortality"].name = "Inmortalidad";
                this.buffList["stic_reflect"].name = "Reflejar";
                this.buffList["stic_counter"].name = "Contraataque";

                this.debuffList["stic_def_dn"].name = "Disminuye la defensa";
                this.debuffList["stic_speed_dn"].name = "Disminuye la velocidad";
                this.debuffList["stic_att_dn"].name = "Disminuye el ataque";
                this.debuffList["stic_blind"].name = "Disminuir probabilidad de golpe";
                this.debuffList["stic_target"].name = "Blanco";
                this.debuffList["stic_buf_impossible"].name = "No se puede potenciar";
                this.debuffList["stic_heal_impossible"].name = "Incurable";
                this.debuffList["stic_stun"].name = "Aturdimiento";
                this.debuffList["stic_provoke"].name = "Provocación";
                this.debuffList["stic_silence"].name = "Silencio";
                this.debuffList["stic_sleep"].name = "Sueño";
                this.debuffList["stic_blood"].name = "Hemorragia";
                this.debuffList["stic_dot"].name = "Veneno";
                this.debuffList["stic_blaze"].name = "Quemadura";
                this.debuffList["stic_vampire"].name = "Toque vampírico";
                this.debuffList["stic_bomb"].name = "Bomba";
              } else if (lingua == "pt") {
                this.buffList["stic_debuf_impossible"].name = "Imune";
                this.buffList["stic_att_up"].name = "Aumentar Ataque";
                this.buffList["stic_att_up2"].name = "Aumentar Ataque (Superior)";
                this.buffList["stic_def_up"].name = "Aumentar Defesa";
                this.buffList["stic_speed_up"].name = "Aumentar Velocidade";
                this.buffList["stic_dodge_up"].name = "Aumentar Evasão";
                this.buffList["stic_protect"].name = "Barreira";
                this.buffList["stic_cri_up"].name = "Aumentar Chance de Crítico";
                this.buffList["stic_cridmg_up"].name = "Aumentar Dano Crítico";
                this.buffList["stic_crires_up"].name = "Aumentar Resistência a Crítico";
                this.buffList["stic_invincible"].name = "Invencível";
                this.buffList["stic_endure"].name = "Anulador de Habilidades";
                this.buffList["stic_heal"].name = "Cura Contínua";
                this.buffList["stic_hide"].name = "Furtividade";
                this.buffList["stic_immortality"].name = "Imortal";
                this.buffList["stic_reflect"].name = "Refletir";
                this.buffList["stic_counter"].name = "Contra-Ataque";

                this.debuffList["stic_def_dn"].name = "Diminuir Defesa";
                this.debuffList["stic_speed_dn"].name = "Diminuir Velocidade";
                this.debuffList["stic_att_dn"].name = "Diminuir Ataque";
                this.debuffList["stic_blind"].name = "Diminuir Chance de Acerto";
                this.debuffList["stic_target"].name = "Alvo";
                this.debuffList["stic_buf_impossible"].name = "Bloqueio de Reforço";
                this.debuffList["stic_heal_impossible"].name = "Incurável";
                this.debuffList["stic_stun"].name = "Atordoamento";
                this.debuffList["stic_provoke"].name = "Provocação";
                this.debuffList["stic_silence"].name = "Silêncio";
                this.debuffList["stic_sleep"].name = "Dormindo";
                this.debuffList["stic_blood"].name = "Sangramento";
                this.debuffList["stic_dot"].name = "Veneno";
                this.debuffList["stic_blaze"].name = "Queimar";
                this.debuffList["stic_vampire"].name = "Toque Vampiresco";
                this.debuffList["stic_bomb"].name = "Bomba";
              } else if (lingua == "de") {
                this.buffList["stic_debuf_impossible"].name = "Immun";
                this.buffList["stic_att_up"].name = "Angriff erhöhen";
                this.buffList["stic_att_up2"].name = "Angriff erhöhen (stark)";
                this.buffList["stic_def_up"].name = "Verteidigung erhöhen";
                this.buffList["stic_speed_up"].name = "Geschwindigkeit erhöhen";
                this.buffList["stic_dodge_up"].name = "Ausweichen erhöhen";
                this.buffList["stic_protect"].name = "Barriere";
                this.buffList["stic_cri_up"].name = "Kritische Trefferquote erhöhen";
                this.buffList["stic_cridmg_up"].name = "Kritischen Schaden erhöhen";
                this.buffList["stic_crires_up"].name = "Kritischen Widerstand erhöhen";
                this.buffList["stic_invincible"].name = "Unbesiegbar";
                this.buffList["stic_endure"].name = "Fertigkeit-Aufhebung";
                this.buffList["stic_heal"].name = "Kontinuierliche Heilung";
                this.buffList["stic_hide"].name = "Tarnung";
                this.buffList["stic_immortality"].name = "Unsterblich";
                this.buffList["stic_reflect"].name = "Reflektieren";
                this.buffList["stic_counter"].name = "Gegenangriff";

                this.debuffList["stic_def_dn"].name = "Verteidigung verringern";
                this.debuffList["stic_speed_dn"].name = "Geschwindigkeit verringern";
                this.debuffList["stic_att_dn"].name = "Angriff verringern";
                this.debuffList["stic_blind"].name = "Trefferquote verringern";
                this.debuffList["stic_target"].name = "Ziel";
                this.debuffList["stic_buf_impossible"].name = "Buffblockade";
                this.debuffList["stic_heal_impossible"].name = "Unheilbar";
                this.debuffList["stic_stun"].name = "Betäubung";
                this.debuffList["stic_provoke"].name = "Provozieren";
                this.debuffList["stic_silence"].name = "Stille";
                this.debuffList["stic_sleep"].name = "Schlaf";
                this.debuffList["stic_blood"].name = "Bluten";
                this.debuffList["stic_dot"].name = "Gift";
                this.debuffList["stic_blaze"].name = "Verbrennen";
                this.debuffList["stic_vampire"].name = "Vampirische Berührung";
                this.debuffList["stic_bomb"].name = "Bombe";
              } else { // eng or ita
                this.buffList["stic_debuf_impossible"].name = "Immunity";
                this.buffList["stic_att_up"].name = "Attack up";
                this.buffList["stic_att_up2"].name = "Attack up (Greater)";
                this.buffList["stic_def_up"].name = "Defense up";
                this.buffList["stic_speed_up"].name = "Speed up";
                this.buffList["stic_dodge_up"].name = "Evasion";
                this.buffList["stic_protect"].name = "Barrier";
                this.buffList["stic_cri_up"].name = "Crit chance up";
                this.buffList["stic_cridmg_up"].name = "Crit damage up";
                this.buffList["stic_crires_up"].name = "Crit Resistance";
                this.buffList["stic_invincible"].name = "Invincibility";
                this.buffList["stic_endure"].name = "Skill nullifier";
                this.buffList["stic_heal"].name = "Continuous Healing";
                this.buffList["stic_hide"].name = "Stealth";
                this.buffList["stic_immortality"].name = "Immortality";
                this.buffList["stic_reflect"].name = "Reflect";
                this.buffList["stic_counter"].name = "Counter";

                this.debuffList["stic_def_dn"].name = "Def down";
                this.debuffList["stic_speed_dn"].name = "Speed down";
                this.debuffList["stic_att_dn"].name = "Attack down";
                this.debuffList["stic_blind"].name = "Blind";
                this.debuffList["stic_target"].name = "Target";
                this.debuffList["stic_buf_impossible"].name = "Unbuffable";
                this.debuffList["stic_heal_impossible"].name = "Unhealable";
                this.debuffList["stic_stun"].name = "Stun";
                this.debuffList["stic_provoke"].name = "Provoke";
                this.debuffList["stic_silence"].name = "Silence";
                this.debuffList["stic_sleep"].name = "Sleep";
                this.debuffList["stic_blood"].name = "Bleed";
                this.debuffList["stic_dot"].name = "Poison";
                this.debuffList["stic_blaze"].name = "Burn";
                this.debuffList["stic_vampire"].name = "Vampire";
                this.debuffList["stic_bomb"].name = "Bomb";
              };
            },
      translateTopics: function (n) {
          if (this.lingua == "jp") {
            switch (n) {
              case 'Criticism':
                return '世界批判';
                break;
              case 'Reality Check':
                return '現実的な話題';
                break;
              case 'Heroic Tale':
                return '武勇伝';
                break;
              case 'Comforting Cheer':
                return '励まし';
                break;
              case 'Cute Cheer':
                return '応援';
                break;
              case 'Heroic Cheer':
                return '英雄応援';
                break;
              case 'Sad Memory':
                return '悲しい思い出';
                break;
              case 'Joyful Memory':
                return '楽しい思い出';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return '幸せな思い出';
                break;
              case 'Unique Comment':
                return '不思議ちゃん';
                break;
              case 'Self-Indulgent':
                return '自己愛';
                break;
              case 'Occult':
                return 'オカルト';
                break;
              case 'Myth':
                return '神話';
                break;
              case 'Bizarre Story':
                return '猟奇的な話';
                break;
              case 'Food Story':
                return 'グルメ';
                break;
              case 'Horror Story':
                return 'ホラー';
                break;
              case 'Gossip':
                return 'ゴシップ';
                break;
              case 'Dream':
                return '夢';
                break;
              case 'Advice':
                return '悩み相談';
                break;
              case 'Complain':
                return '愚痴';
                break;
              case 'Faith':
              case 'Belief':
                return '信念';
                break;
              case 'Interesting Story':
                return '冒険話';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "cn") {
            switch (n) {
              case 'Criticism':
                return '批判世界';
                break;
              case 'Reality Check':
                return '正视现实';
                break;
              case 'Heroic Tale':
                return '英雄故事';
                break;
              case 'Comforting Cheer':
                return '安慰助阵';
                break;
              case 'Cute Cheer':
                return '撒娇助阵';
                break;
              case 'Heroic Cheer':
                return '英雄式助阵';
                break;
              case 'Sad Memory':
                return '伤心回忆';
                break;
              case 'Joyful Memory':
                return '愉快回忆';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return '幸福回忆';
                break;
              case 'Unique Comment':
                return '4次元的发言';
                break;
              case 'Self-Indulgent':
                return '自我陶醉';
                break;
              case 'Occult':
                return '秘术';
                break;
              case 'Myth':
                return '神话';
                break;
              case 'Bizarre Story':
                return '猎奇的故事';
                break;
              case 'Food Story':
                return '食物故事';
                break;
              case 'Horror Story':
                return '恐怖故事';
                break;
              case 'Gossip':
                return '八卦';
                break;
              case 'Dream':
                return '梦';
                break;
              case 'Advice':
                return '烦恼咨询';
                break;
              case 'Complain':
                return '耍赖';
                break;
              case 'Faith':
              case 'Belief':
                return '信念';
                break;
              case 'Interesting Story':
                return '冒险故事';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "zht") {
            switch (n) {
              case 'Criticism':
                return '批判世界';
                break;
              case 'Reality Check':
                return '正視現實';
                break;
              case 'Heroic Tale':
                return '英雄故事';
                break;
              case 'Comforting Cheer':
                return '安慰助陣';
                break;
              case 'Cute Cheer':
                return '撒嬌助陣';
                break;
              case 'Heroic Cheer':
                return '英雄式助陣';
                break;
              case 'Sad Memory':
                return '傷心回憶';
                break;
              case 'Joyful Memory':
                return '愉快回憶';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return '幸福回憶';
                break;
              case 'Unique Comment':
                return '4次元的發言';
                break;
              case 'Self-Indulgent':
                return '自我陶醉';
                break;
              case 'Occult':
                return '秘術';
                break;
              case 'Myth':
                return '神話';
                break;
              case 'Bizarre Story':
                return '獵奇的故事';
                break;
              case 'Food Story':
                return '食物故事';
                break;
              case 'Horror Story':
                return '恐怖故事';
                break;
              case 'Gossip':
                return '八卦';
                break;
              case 'Dream':
                return '夢';
                break;
              case 'Advice':
                return '煩惱諮詢';
                break;
              case 'Complain':
                return '耍賴';
                break;
              case 'Faith':
              case 'Belief':
                return '信念';
                break;
              case 'Interesting Story':
                return '冒險故事';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "fr") {
            switch (n) {
              case 'Criticism':
                return 'Critique';
                break;
              case 'Reality Check':
                return 'Rappel à la réalité';
                break;
              case 'Heroic Tale':
                return 'Histoire héroïque';
                break;
              case 'Comforting Cheer':
                return 'Encouragement consolant';
                break;
              case 'Cute Cheer':
                return 'Encouragement adorable';
                break;
              case 'Heroic Cheer':
                return 'Encouragement héroïque';
                break;
              case 'Sad Memory':
                return 'Souvenir triste';
                break;
              case 'Joyful Memory':
                return 'Souvenir joyeux';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return 'Souvenir heureux';
                break;
              case 'Unique Comment':
                return 'Commentaire particulier';
                break;
              case 'Self-Indulgent':
                return 'Complaisant';
                break;
              case 'Occult':
                return 'Occulte';
                break;
              case 'Myth':
                return 'Mythe';
                break;
              case 'Bizarre Story':
                return 'Histoire bizarre';
                break;
              case 'Food Story':
                return 'Histoire appétissante';
                break;
              case 'Horror Story':
                return 'Histoire lugubre';
                break;
              case 'Gossip':
                return 'Potin';
                break;
              case 'Dream':
                return 'Rêve';
                break;
              case 'Advice':
                return 'Conseil';
                break;
              case 'Complain':
                return 'Plainte';
                break;
              case 'Faith':
              case 'Belief':
                return 'Croyance';
                break;
              case 'Interesting Story':
                return 'Anecdote';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "th") {
            switch (n) {
              case 'Criticism':
                return 'วิพากษ์วิจารณ์';
                break;
              case 'Reality Check':
                return 'ย้ำเตือนถึงความเป็นจริง';
                break;
              case 'Heroic Tale':
                return 'เรื่องเล่าวีรกรรม';
                break;
              case 'Comforting Cheer':
                return 'ให้กำลังใจเพื่อปลอบโยน';
                break;
              case 'Cute Cheer':
                return 'ให้กำลังใจอย่างน่ารัก';
                break;
              case 'Heroic Cheer':
                return 'ให้กำลังใจอย่างกล้าหาญ';
                break;
              case 'Sad Memory':
                return 'ความทรงจำแสนเศร้า';
                break;
              case 'Joyful Memory':
                return 'ความทรงจำอันเบิกบาน';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return 'ความทรงจำแสนสุข';
                break;
              case 'Unique Comment':
                return 'ความคิดเห็นที่เป็นเอกลักษณ์';
                break;
              case 'Self-Indulgent':
                return 'พูดจาหลงตัวเอง';
                break;
              case 'Occult':
                return 'ลัทธิ';
                break;
              case 'Myth':
                return 'ตำนาน';
                break;
              case 'Bizarre Story':
                return 'เรื่องประหลาด';
                break;
              case 'Food Story':
                return 'เรื่องอาหาร';
                break;
              case 'Horror Story':
                return 'เรื่องสยอง';
                break;
              case 'Gossip':
                return 'เรื่องกอสซิป';
                break;
              case 'Dream':
                return 'ความฝัน';
                break;
              case 'Advice':
                return 'คำแนะนำ';
                break;
              case 'Complain':
                return 'คำบ่น';
                break;
              case 'Faith':
              case 'Belief':
                return 'ความเชื่อ';
                break;
              case 'Interesting Story':
                return 'เรื่องน่าสนใจ';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "kr") {
            switch (n) {
              case 'Criticism':
                return '세계 비판';
                break;
              case 'Reality Check':
                return '현실직시';
                break;
              case 'Heroic Tale':
                return '무용담';
                break;
              case 'Comforting Cheer':
                return '위로 응원';
                break;
              case 'Cute Cheer':
                return '애교 응원';
                break;
              case 'Heroic Cheer':
                return '영웅적 응원';
                break;
              case 'Sad Memory':
                return '슬픈 추억';
                break;
              case 'Joyful Memory':
                return '즐거운 추억';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return '행복한 추억';
                break;
              case 'Unique Comment':
                return '차원 발언';
                break;
              case 'Self-Indulgent':
                return '자아도취';
                break;
              case 'Occult':
                return '오컬트';
                break;
              case 'Myth':
                return '신화';
                break;
              case 'Bizarre Story':
                return '엽기적 이야기';
                break;
              case 'Food Story':
                return '음식 이야기';
                break;
              case 'Horror Story':
                return '공포 이야기';
                break;
              case 'Gossip':
                return '가십';
                break;
              case 'Dream':
                return '꿈';
                break;
              case 'Advice':
                return '고민 상담';
                break;
              case 'Complain':
                return '투정';
                break;
              case 'Faith':
              case 'Belief':
                return '신념';
                break;
              case 'Interesting Story':
                return '모험이야기';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "es") {
            switch (n) {
              case 'Criticism':
                return 'Crítica';
                break;
              case 'Reality Check':
                return 'Asume la realidad';
                break;
              case 'Heroic Tale':
                return 'Relato heroico';
                break;
              case 'Comforting Cheer':
                return 'Vitoreo reconfortante';
                break;
              case 'Cute Cheer':
                return 'Vitoreo tierno';
                break;
              case 'Heroic Cheer':
                return 'Vitoreo heroico';
                break;
              case 'Sad Memory':
                return 'Recuerdo triste';
                break;
              case 'Joyful Memory':
                return 'Recuerdo feliz';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return 'Recuerdo alegre';
                break;
              case 'Unique Comment':
                return 'Comentario único';
                break;
              case 'Self-Indulgent':
                return 'Hedonista';
                break;
              case 'Occult':
                return 'Místico';
                break;
              case 'Myth':
                return 'Mito';
                break;
              case 'Bizarre Story':
                return 'Historia extraña';
                break;
              case 'Food Story':
                return 'Historia sobre comida';
                break;
              case 'Horror Story':
                return 'Historia de terror';
                break;
              case 'Gossip':
                return 'Rumor';
                break;
              case 'Dream':
                return 'Sueño';
                break;
              case 'Advice':
                return 'Consejo';
                break;
              case 'Complain':
                return 'Queja';
                break;
              case 'Faith':
              case 'Belief':
                return 'Creencia';
                break;
              case 'Interesting Story':
                return 'Historia interesante';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "pt") {
            switch (n) {
              case 'Criticism':
                return 'Crítica';
                break;
              case 'Reality Check':
                return 'Papo Realista';
                break;
              case 'Heroic Tale':
                return 'Conto Heroico';
                break;
              case 'Comforting Cheer':
                return 'Consolar';
                break;
              case 'Cute Cheer':
                return 'Animar';
                break;
              case 'Heroic Cheer':
                return 'Encorajar';
                break;
              case 'Sad Memory':
                return 'Lembrança Triste';
                break;
              case 'Joyful Memory':
                return 'Lembrança Animada';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return 'Lembrança Feliz';
                break;
              case 'Unique Comment':
                return 'Comentário Singular';
                break;
              case 'Self-Indulgent':
                return 'Complacência';
                break;
              case 'Occult':
                return 'Ocultismo';
                break;
              case 'Myth':
                return 'Mito';
                break;
              case 'Bizarre Story':
                return 'História Bizarra';
                break;
              case 'Food Story':
                return 'História de Comida';
                break;
              case 'Horror Story':
                return 'História de Terror';
                break;
              case 'Gossip':
                return 'Fofoca';
                break;
              case 'Dream':
                return 'Sonho';
                break;
              case 'Advice':
                return 'Conselho';
                break;
              case 'Complain':
                return 'Reclamação';
                break;
              case 'Faith':
              case 'Belief':
                return 'Crença';
                break;
              case 'Interesting Story':
                return 'História Interessante';
                break;
              default:
                return n;
                break;
            };
          } else if (this.lingua == "de") {
            switch (n) {
              case 'Criticism':
                return 'Kritik';
                break;
              case 'Reality Check':
                return 'Realitäts-Check';
                break;
              case 'Heroic Tale':
                return 'Heroische Erzählung';
                break;
              case 'Comforting Cheer':
                return 'Tröstlicher Jubel';
                break;
              case 'Cute Cheer':
                return 'Niedlicher Jubel';
                break;
              case 'Heroic Cheer':
                return 'Heroischer Jubel';
                break;
              case 'Sad Memory':
                return 'Traurige Erinnerung';
                break;
              case 'Joyful Memory':
                return 'Fröhliche Erinnerung';
                break;
              case 'Happy Memory':
              case 'Happy Memories':
                return 'Glückliche Erinnerung';
                break;
              case 'Unique Comment':
                return 'Einzigartiger Kommentar';
                break;
              case 'Self-Indulgent':
                return 'Ausschweifend';
                break;
              case 'Occult':
                return 'Okkult';
                break;
              case 'Myth':
                return 'Mythos';
                break;
              case 'Bizarre Story':
                return 'Bizarre Geschichte';
                break;
              case 'Food Story':
                return 'Nahrungsgeschichte';
                break;
              case 'Horror Story':
                return 'Horrorgeschichte';
                break;
              case 'Gossip':
                return 'Tratsch';
                break;
              case 'Dream':
                return 'Traum';
                break;
              case 'Advice':
                return 'Rat';
                break;
              case 'Complain':
                return 'Beschwerde';
                break;
              case 'Faith':
              case 'Belief':
                return 'Glaube';
                break;
              case 'Interesting Story':
                return 'Interessante Geschichte';
                break;
              default:
                return n;
                break;
            };
          } else { // EN
            switch (n) {
              case 'Belief':
                return 'Faith';
                break;
              default:
           	return n;
	    };
          };
      },
      getUserHeroesBoot: function () { // read user's local storage team
        var tmp = localStorage.getItem('Heroes') ? localStorage.getItem('Heroes') : '{}';
        tmp = JSON.parse(tmp);
        if (tmp.constructor === Array) tmp = {};
        if (Object.keys(tmp).length > 0 && Object.keys(this.HeroDB).length) {
          for (var key in tmp) {
            if (!this.HeroDB[key] ) { // Check if heroes exist in the database
              if (this.HeroDB[tmp[key]._id]) { //convert to _id as key
                tmp[tmp[key]._id] = tmp[key];
                delete tmp[key];
              } else { // hero _id does not exist -> remove hero from user's roster to avoid boot problems
                delete tmp[key];
              };
            };
          };
        };
        this.myHeroesList = tmp;
        if (this.myHeroesList['dark-tyrant-tenebria']) delete this.myHeroesList['dark-tyrant-tenebria'];
        this.displayMyHeroes = Object.keys(this.myHeroesList);
        this.rosterLength = Object.keys(this.myHeroesList).length;
        //this.updateUserData(); // write data to local storage
      }, 
      getUserHeroesURL(e) {
        try {
          var roster = JSON.parse(atob(e));
          for (var i = 0; i < roster.length; i++) {
            if (this.HeroDB[roster[i]]) {
              this.myHeroesList[roster[i]] = this.HeroDB[roster[i]];
            };
          };
          if (this.myHeroesList['dark-tyrant-tenebria']) delete this.myHeroesList['dark-tyrant-tenebria'];
          this.displayMyHeroes = Object.keys(this.myHeroesList);
          this.rosterLength = Object.keys(this.myHeroesList).length;
          this.updateUserData();
        } catch (err) { // if URL is corrupted
          console.log("Error: corrupted URL");
          snackbarMessage("Error: corrupted URL roster!<br>Loading from local storage.");
          this.getUserHeroesBoot(); // get heroes list from file
        };
      },
      sortCharacters: function (a,o=['data','name']) {
        !Array.isArray(o)?o=[null,o]:null;
        if (!o[0] || o[0] === 'data') {
          if (o[1]!='rarity' && o[1]!='date') return a.sort((x, y) => { return (this.thisHeroData(x)[o[1]] > this.thisHeroData(y)[o[1]] ) - (this.thisHeroData(x)[o[1]] < this.thisHeroData(y)[o[1]] ) || (this.thisHeroData(x).name > this.thisHeroData(y).name ) - (this.thisHeroData(x).name < this.thisHeroData(y).name ) });
          else if (o[1] =="rarity") return a.sort((x, y) => { return (this.thisHeroData(x)[o[1]] < this.thisHeroData(y)[o[1]] ) - (this.thisHeroData(x)[o[1]] > this.thisHeroData(y)[o[1]] ) || (this.thisHeroData(x).name > this.thisHeroData(y).name ) - (this.thisHeroData(x).name < this.thisHeroData(y).name ) });
          else return a;
        } else if (o[0]==='c_values') {
          return a.sort((x, y) => { return (this.thisHeroData(x).camping.values[o[1]] < this.thisHeroData(y).camping.values[o[1]] ) - (this.thisHeroData(x).camping.values[o[1]] > this.thisHeroData(y).camping.values[o[1]] ) || (this.thisHeroData(x).name > this.thisHeroData(y).name ) - (this.thisHeroData(x).name < this.thisHeroData(y).name ) });
        } else
          return a;
      },
      boot: function () {
        try {
          var urlParams = new URLSearchParams(window.location.search);
          $.when(
            $.ajax({
              url: "../../data/HeroDatabase.json",
              type: 'GET',
              contentType: 'application/json'
            }),
            $.ajax({
              url: "../../data/CampingData.json",
              type: 'GET',
              contentType: 'application/json'
            })
          ).then((data, cData) => {
            var db = {}
            for (var hero in cData[0]) {
              if (data[0][hero] && cData[0][hero].camping) {
                if (!cData[0][hero].camping.values) {
                  cData[0][hero].camping.values = CampDataBuilder(cData[0][hero].camping.personalities);
                }
                db[hero] = Object.assign({}, cData[0][hero], data[0][hero])
              }
            }
            this.HeroDB = db;
            if (!urlParams.get("camproster")) { // get roster from file
              this.getUserHeroesBoot();
            } else {// get roster from url
              this.getUserHeroesURL(urlParams.get("camproster"));
              window.history.pushState("", "", window.location.pathname); // remove ?camproster= from the URL to avoid accidental refreshes replacing your current team
            };
              this.filtroTuttiGliEroi({tipo:'refresh',casella:'',value:'',className: 'search_hero_filter', name: 'bodyLoad'},'AllHeroes');
              this.inizializzazione = false;
          }).catch( err => {
            alert('Fetch error')
          })
          this.impostaLingua();
          this.inizializzaione();
        } catch (err) {
          console.log(err);
          document.getElementById("caricamentoIniziale").innerHTML += "<span style='position: fixed; bottom: 0; right: 0; color: red; padding: 10px'><pre>FATAL ERROR<br>"+err+"<br><span style='color:green'>Please retry or contact me.</span></pre></span>";
        };
      },
      inizializzaione: function () {
        this.translatedName = {};
        self = this;
        $.ajax({
          url: "https://api.epicsevendb.com/hero?lang=" + this.lingua,
          type: 'GET',
          contentType: 'application/json',
          success: (response) => {
            response.results.forEach(function(item) {
              self.translatedName[item._id] = item.name;
            });
            let missing = {
              "dark-tyrant-tenebria": {cn: "残月的暴君泰妮布里雅", zht: "殘月的暴君泰妮布里雅", fr: "Tenebria tyran de l'astre violine"}
            };
            for (var id in missing) {
              if (missing[id][this.lingua]) self.translatedName[id] = missing[id][this.lingua];
            };
            this.filtroTuttiGliEroi({tipo:'refresh',casella:'',value:'',className: 'search_hero_filter', name: 'bodyLoad'},'AllHeroes');
          },
          error: (jqXHR, textStatus, errorThrown) => {
            this.filtroTuttiGliEroi({tipo:'refresh',casella:'',value:'',className: 'search_hero_filter', name: 'bodyLoad'},'AllHeroes');
            snackbarMessage("Cannot connect to EpicSevenDB API. Using english gamedata.");
          }
        });
      }
    },
    computed: {
        databaseNumber: function() {
          return Object.keys(this.HeroDB).length-this.rosterLength;
        },
        sortedHeroDB: function () {
          this.databaseNumber;
          if (this.databaseNumber<1) return [];
          var sortBy = this.databaseSort, list = Object.keys(this.HeroDB), banned = ["dark-tyrant-tenebria"];
          for (var i=0; i<list.length;i++) if (this.myHeroesList[list[i]] || banned.includes(list[i])) list.splice(list.indexOf(list[i]),1),i--;
          return this.sortCharacters(list,sortBy);
        },
        roster: function() {
          this.rosterLength;
          var sortBy = this.rosterSort;
          return this.sortCharacters(Object.keys(this.myHeroesList),sortBy);
        },
        computedGetSavedTeamsStats: function () {
          this.getSavedTeamsStats();
        },
        calcolaRisultati: function () { // in computed per evitare di calcolare 2 volte il risultato se non si è cambiato niente
            //resetta per un nuovo calcolo
            this.risultati = [];
            //Richiama questi valori per far capire a vue di ricalcolare se sono cambiati
            this.rosterLength;
            this.classe;
            this.elemento;
            this.debuffs;
            this.buffs;
            this.AoE;
            this.noS1debuffs;
            this.noDebuffs;
            this.mustIncludeDispel;
            this.customizedResuts;
            if (Object.keys(this.myHeroesList).length > 3) {
              this.isLoadingResults = true; // mostra animazione di caricamento
              console.log("Start calculating...");
              var campList = Object.keys(this.myHeroesList);
              if (this.locked.length > 0 ) {
                for (var i = 0; i< this.locked.length; i++){
                    campList.splice( campList.indexOf(this.locked[i]),1);
                  };
              };
              try {
                camperino.postMessage({HeroDB: this.HeroDB, myHeroesList: this.myHeroesList, campList: campList, locked: this.locked, classe: this.classe, elemento: this.elemento, debuffs: this.debuffs, buffs: this.buffs, AoE: this.AoE, noS1debuffs: this.noS1debuffs, noDebuffs: this.noDebuffs, mustIncludeDispel: this.mustIncludeDispel, mustIncludeCleanser: this.mustIncludeCleanser, cartesianLock: this.cartesian_lock, preferenzeRisultati: this.customizedResuts, risultati: []});
                this.numeroCombinazioniPossibili = Combinatorics.bigCombination(campList,4-this.locked.length).length;
              } catch (err) {
                this.isLoadingResults = false; // remove angelica loading
                snackbarMessage(`Error: ` + err);
              };
            };
            return null;
      }
  }, // computed
  watch: {
    risultati: function () { // when new results are calculated go back to page 1
      this.currentResultsPage = 1;
    },
    rosterLength: function () {
      this.sortedHeroDB;
    }
  },
  mounted () {
  },
  created () {console.log("CeciliaBot is booting..."), this.boot()}
});

function debounce(func, wait, immediate) {
  var timeout;
  return function executedFunction() {
    var context = this;
    var args = arguments;
	    
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    var callNow = immediate && !timeout;
	
    clearTimeout(timeout);

    timeout = setTimeout(later, wait);
	
    if (callNow) func.apply(context, args);
  };
};


  var camperinoMessage = function (e) {
    //mandaNotificaCompletamento();
    if (e.data.error)
      mandaNotificaCompletamento(),
      snackbarMessage(app.strings["results_error"] + `: ` + app.strings[e.data.error]), /* throw error */
      document.getElementById('calculationPer').parentNode.style.display = "none",
      document.getElementById('calculationPer').style.width = "0%",
      app.isLoadingResults = false;
    else if (e.data.status) {
      document.getElementById('calculationPer').parentNode.style.display = "block";
      document.getElementById('calculationPer').previousElementSibling.innerText = e.data.status + "%";
      document.getElementById('calculationPer').style.width = e.data.status + "%";
    }
    else if (e.data.risultati)
      mandaNotificaCompletamento(),
      app.risultati = e.data.risultati,
      document.getElementById('calculationPer').parentNode.style.display = "none",
      document.getElementById('calculationPer').style.width = "0%",
      app.isLoadingResults = false;
  };
  // Genera un worker per eseguire i calcoli del camp
  var camperino = new Worker('./worker.js');
  camperino.onmessage = function(e) {
    camperinoMessage(e);
  };
  camperino.onerror = function(err) {
    console.log(err)
    snackbarMessage(`worker.js unknown error. Please retry or refresh this page.`)
    app.isLoadingResults = false;
  };
  function restartCamperino() { // abort calculation function
    var answer = window.confirm(app.strings.confirm_worker_termination);
    if (answer) { // terminate
      camperino.terminate();
      camperino = new Worker('./worker.js');
      var copy = app.debuffs.slice();
      app.debuffs.push("aaaa"); // add something to trigger a new calculation attempt 
      app.debuffs = copy; // restore debuff list
      app.isLoadingResults = false; // disattiva angelica
      document.getElementById('calculationPer').parentNode.style.display = "none",
      camperino.onmessage = function(e) {
        camperinoMessage(e);
      };
      camperino.onerror = function(err) {
        console.log(err);
        snackbarMessage(`Camping fatal error. Please refresh this page.`);
        app.isLoadingResults = false;
      };
    };
  };
  /*
  window.onerror = function (message, file, line, col, error) {
   snackbarMessage("ERROR<br>"+error.message + "<br>"+file+" "+line+":"+col);
   return false;
  };
  */
  window.addEventListener("error", function (e) {
    if (e.error && e.error.message.indexOf("e.target.parentNode")===-1) snackbarMessage("ERROR<br>"+e.message + "<br>"+e.error.fileName+" "+e.error.lineNumber+":"+e.error.columnNumber);
    return false;
  });
</script>
<script src="./components/lab-maker.js" defer></script>
</body>
</html>